diff options
author | hongbotian <hongbo.tianhongbo@huawei.com> | 2015-11-30 03:10:21 -0500 |
---|---|---|
committer | hongbotian <hongbo.tianhongbo@huawei.com> | 2015-11-30 03:10:21 -0500 |
commit | c0b7206652b2852bc574694e7ba07ba1c2acdc00 (patch) | |
tree | 5cb95cb0e19e03610525903df46279df2c3b7eb1 /rubbos/app/httpd-2.0.64/server | |
parent | b6d3d6e668b793220f2d3af1bc3e828553dc3fe6 (diff) |
delete app
Change-Id: Id4c572809969ebe89e946e88063eaed262cff3f2
Signed-off-by: hongbotian <hongbo.tianhongbo@huawei.com>
Diffstat (limited to 'rubbos/app/httpd-2.0.64/server')
206 files changed, 0 insertions, 44235 deletions
diff --git a/rubbos/app/httpd-2.0.64/server/.deps b/rubbos/app/httpd-2.0.64/server/.deps deleted file mode 100644 index e69de29b..00000000 --- a/rubbos/app/httpd-2.0.64/server/.deps +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.indent.pro b/rubbos/app/httpd-2.0.64/server/.indent.pro deleted file mode 100644 index a9fbe9f9..00000000 --- a/rubbos/app/httpd-2.0.64/server/.indent.pro +++ /dev/null @@ -1,54 +0,0 @@ --i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 --TBUFF --TFILE --TTRANS --TUINT4 --T_trans --Tallow_options_t --Tapache_sfio --Tarray_header --Tbool_int --Tbuf_area --Tbuff_struct --Tbuffy --Tcmd_how --Tcmd_parms --Tcommand_rec --Tcommand_struct --Tconn_rec --Tcore_dir_config --Tcore_server_config --Tdir_maker_func --Tevent --Tglobals_s --Thandler_func --Thandler_rec --Tjoblist_s --Tlisten_rec --Tmerger_func --Tmode_t --Tmodule --Tmodule_struct --Tmutex --Tn_long --Tother_child_rec --Toverrides_t --Tparent_score --Tpid_t --Tpiped_log --Tpool --Trequest_rec --Trequire_line --Trlim_t --Tscoreboard --Tsemaphore --Tserver_addr_rec --Tserver_rec --Tserver_rec_chain --Tshort_score --Ttable --Ttable_entry --Tthread --Tu_wide_int --Tvtime_t --Twide_int diff --git a/rubbos/app/httpd-2.0.64/server/.libs/buildmark.o b/rubbos/app/httpd-2.0.64/server/.libs/buildmark.o Binary files differdeleted file mode 100644 index 8dca2913..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/buildmark.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/config.o b/rubbos/app/httpd-2.0.64/server/.libs/config.o Binary files differdeleted file mode 100644 index c5e795ab..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/config.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/connection.o b/rubbos/app/httpd-2.0.64/server/.libs/connection.o Binary files differdeleted file mode 100644 index 358e13a0..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/connection.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/core.o b/rubbos/app/httpd-2.0.64/server/.libs/core.o Binary files differdeleted file mode 100644 index df7ffe55..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/core.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/eoc_bucket.o b/rubbos/app/httpd-2.0.64/server/.libs/eoc_bucket.o Binary files differdeleted file mode 100644 index 9bdedb94..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/eoc_bucket.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/error_bucket.o b/rubbos/app/httpd-2.0.64/server/.libs/error_bucket.o Binary files differdeleted file mode 100644 index 03198e00..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/error_bucket.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/exports.o b/rubbos/app/httpd-2.0.64/server/.libs/exports.o Binary files differdeleted file mode 100644 index a93c0eed..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/exports.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/gen_test_char.o b/rubbos/app/httpd-2.0.64/server/.libs/gen_test_char.o Binary files differdeleted file mode 100644 index 7fb0cbe2..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/gen_test_char.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/libmain.a b/rubbos/app/httpd-2.0.64/server/.libs/libmain.a Binary files differdeleted file mode 100644 index 5ac351d1..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/libmain.a +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/libmain.la b/rubbos/app/httpd-2.0.64/server/.libs/libmain.la deleted file mode 100644 index 88fb990a..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/libmain.la +++ /dev/null @@ -1,35 +0,0 @@ -# libmain.la - a libtool library file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='' - -# Names of this library. -library_names='' - -# The name of the static archive. -old_library='libmain.a' - -# Libraries that this one depends upon. -dependency_libs=' -L/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/xml/expat/lib' - -# Version information for libmain. -current= -age= -revision= - -# Is this an already installed library? -installed=no - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='' diff --git a/rubbos/app/httpd-2.0.64/server/.libs/listen.o b/rubbos/app/httpd-2.0.64/server/.libs/listen.o Binary files differdeleted file mode 100644 index 3e769684..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/listen.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/log.o b/rubbos/app/httpd-2.0.64/server/.libs/log.o Binary files differdeleted file mode 100644 index d5f2ee13..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/log.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/main.o b/rubbos/app/httpd-2.0.64/server/.libs/main.o Binary files differdeleted file mode 100644 index 0602d80a..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/main.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/mpm_common.o b/rubbos/app/httpd-2.0.64/server/.libs/mpm_common.o Binary files differdeleted file mode 100644 index cd06b1d5..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/mpm_common.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/protocol.o b/rubbos/app/httpd-2.0.64/server/.libs/protocol.o Binary files differdeleted file mode 100644 index dfe97714..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/protocol.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/provider.o b/rubbos/app/httpd-2.0.64/server/.libs/provider.o Binary files differdeleted file mode 100644 index 84297cfb..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/provider.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/request.o b/rubbos/app/httpd-2.0.64/server/.libs/request.o Binary files differdeleted file mode 100644 index 136bd10a..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/request.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/rfc1413.o b/rubbos/app/httpd-2.0.64/server/.libs/rfc1413.o Binary files differdeleted file mode 100644 index 04b1ff54..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/rfc1413.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/scoreboard.o b/rubbos/app/httpd-2.0.64/server/.libs/scoreboard.o Binary files differdeleted file mode 100644 index 58be9313..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/scoreboard.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util.o b/rubbos/app/httpd-2.0.64/server/.libs/util.o Binary files differdeleted file mode 100644 index c297bbc1..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_cfgtree.o b/rubbos/app/httpd-2.0.64/server/.libs/util_cfgtree.o Binary files differdeleted file mode 100644 index 55b3915f..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_cfgtree.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_charset.o b/rubbos/app/httpd-2.0.64/server/.libs/util_charset.o Binary files differdeleted file mode 100644 index fbf7c134..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_charset.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_debug.o b/rubbos/app/httpd-2.0.64/server/.libs/util_debug.o Binary files differdeleted file mode 100644 index feea30b4..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_debug.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_ebcdic.o b/rubbos/app/httpd-2.0.64/server/.libs/util_ebcdic.o Binary files differdeleted file mode 100644 index 0b072231..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_ebcdic.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_filter.o b/rubbos/app/httpd-2.0.64/server/.libs/util_filter.o Binary files differdeleted file mode 100644 index 80950d79..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_filter.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_md5.o b/rubbos/app/httpd-2.0.64/server/.libs/util_md5.o Binary files differdeleted file mode 100644 index 172bfbf4..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_md5.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_script.o b/rubbos/app/httpd-2.0.64/server/.libs/util_script.o Binary files differdeleted file mode 100644 index 3e7d092e..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_script.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_time.o b/rubbos/app/httpd-2.0.64/server/.libs/util_time.o Binary files differdeleted file mode 100644 index b3ca86f4..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_time.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/util_xml.o b/rubbos/app/httpd-2.0.64/server/.libs/util_xml.o Binary files differdeleted file mode 100644 index 295b9bc4..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/util_xml.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/.libs/vhost.o b/rubbos/app/httpd-2.0.64/server/.libs/vhost.o Binary files differdeleted file mode 100644 index 7e23e87a..00000000 --- a/rubbos/app/httpd-2.0.64/server/.libs/vhost.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/Makefile b/rubbos/app/httpd-2.0.64/server/Makefile deleted file mode 100644 index 3c3ad912..00000000 --- a/rubbos/app/httpd-2.0.64/server/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -top_srcdir = /bottlenecks/rubbos/app/httpd-2.0.64 -top_builddir = /bottlenecks/rubbos/app/httpd-2.0.64 -srcdir = /bottlenecks/rubbos/app/httpd-2.0.64/server -builddir = /bottlenecks/rubbos/app/httpd-2.0.64/server -VPATH = /bottlenecks/rubbos/app/httpd-2.0.64/server - -CLEAN_TARGETS = gen_test_char test_char.h \ - ApacheCoreOS2.def -DISTCLEAN_TARGETS = httpd.exp -EXTRACLEAN_TARGETS = export_files exports.c export_vars.h - -SUBDIRS = mpm - -LTLIBRARY_NAME = libmain.la -LTLIBRARY_SOURCES = \ - test_char.h \ - config.c log.c main.c vhost.c util.c \ - util_script.c util_md5.c util_cfgtree.c util_ebcdic.c util_time.c \ - rfc1413.c connection.c listen.c \ - mpm_common.c util_charset.c util_debug.c util_xml.c \ - util_filter.c exports.c buildmark.c \ - scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \ - eoc_bucket.c - -TARGETS = delete-exports $(LTLIBRARY_NAME) $(CORE_IMPLIB_FILE) export_vars.h httpd.exp - -include $(top_builddir)/build/rules.mk -include $(top_srcdir)/build/library.mk - -gen_test_char_OBJECTS = gen_test_char.lo util_debug.lo -gen_test_char: $(gen_test_char_OBJECTS) - $(LINK) $(EXTRA_LDFLAGS) $(gen_test_char_OBJECTS) $(EXTRA_LIBS) - -test_char.h: gen_test_char - ./gen_test_char > test_char.h - -util.lo: test_char.h - -EXPORT_DIRS = $(top_srcdir)/include $(top_srcdir)/os/$(OS_DIR) $(top_srcdir)/modules/http -EXPORT_DIRS_APR = $(APR_INCLUDEDIR) $(APU_INCLUDEDIR) - -# If export_files is a dependency here, but we remove it during this stage, -# when exports.c is generated, make will not detect that export_files is no -# longer here and deadlock. So, export_files can't be a dependency of -# delete-exports. -delete-exports: - @if test -f exports.c; then \ - if test -f export_files; then \ - files=`cat export_files`; \ - headers="`find $$files -newer exports.c`"; \ - if test -n "$$headers"; then \ - echo Found newer headers. Will rebuild exports.c.; \ - echo rm -f exports.c export_files; \ - rm -f exports.c export_files; \ - fi; \ - else \ - rm -f exports.c; \ - fi; \ - fi - -export_files: - tmp=export_files_unsorted.txt; \ - rm -f $$tmp && touch $$tmp; \ - for dir in $(EXPORT_DIRS); do \ - ls $$dir/*.h >> $$tmp; \ - done; \ - for dir in $(EXPORT_DIRS_APR); do \ - (ls $$dir/ap[ru].h $$dir/ap[ru]_*.h >> $$tmp 2>/dev/null); \ - done; \ - sort -u $$tmp > $@; \ - rm -f $$tmp - -exports.c: export_files - $(AWK) -f $(top_srcdir)/build/make_exports.awk `cat $?` > $@ - -export_vars.h: export_files - $(AWK) -f $(top_srcdir)/build/make_var_export.awk `cat $?` > $@ - -# Rule to make def file for OS/2 core dll -ApacheCoreOS2.def: exports.c export_vars.h $(top_srcdir)/os/$(OS_DIR)/core_header.def - cat $(top_srcdir)/os/$(OS_DIR)/core_header.def > $@ - $(CPP) $< $(ALL_CPPFLAGS) $(ALL_INCLUDES) | grep "ap_hack_" | sed -e 's/^.*[)]\(.*\);$$/ "\1"/' >> $@ - $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep "^[a-z]" | sed -e 's/^\(.*\)$$/ "\1"/' >> $@ - -# Rule to make exp file for AIX DSOs -httpd.exp: exports.c export_vars.h - @echo "#! ." > $@ - @echo "* This file was AUTOGENERATED at build time." >> $@ - @echo "* Please do not edit by hand." >> $@ - $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) exports.c | grep "ap_hack_" | grep -v apr_ | sed -e 's/^.*[)]\(.*\);$$/\1/' >> $@ - $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep -v apr_ | sed -e 's/^\#[^!]*//' | sed -e '/^$$/d' >> $@ diff --git a/rubbos/app/httpd-2.0.64/server/Makefile.in b/rubbos/app/httpd-2.0.64/server/Makefile.in deleted file mode 100644 index 12dc7d87..00000000 --- a/rubbos/app/httpd-2.0.64/server/Makefile.in +++ /dev/null @@ -1,86 +0,0 @@ - -CLEAN_TARGETS = gen_test_char test_char.h \ - ApacheCoreOS2.def -DISTCLEAN_TARGETS = httpd.exp -EXTRACLEAN_TARGETS = export_files exports.c export_vars.h - -SUBDIRS = mpm - -LTLIBRARY_NAME = libmain.la -LTLIBRARY_SOURCES = \ - test_char.h \ - config.c log.c main.c vhost.c util.c \ - util_script.c util_md5.c util_cfgtree.c util_ebcdic.c util_time.c \ - rfc1413.c connection.c listen.c \ - mpm_common.c util_charset.c util_debug.c util_xml.c \ - util_filter.c exports.c buildmark.c \ - scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \ - eoc_bucket.c - -TARGETS = delete-exports $(LTLIBRARY_NAME) $(CORE_IMPLIB_FILE) export_vars.h httpd.exp - -include $(top_builddir)/build/rules.mk -include $(top_srcdir)/build/library.mk - -gen_test_char_OBJECTS = gen_test_char.lo util_debug.lo -gen_test_char: $(gen_test_char_OBJECTS) - $(LINK) $(EXTRA_LDFLAGS) $(gen_test_char_OBJECTS) $(EXTRA_LIBS) - -test_char.h: gen_test_char - ./gen_test_char > test_char.h - -util.lo: test_char.h - -EXPORT_DIRS = $(top_srcdir)/include $(top_srcdir)/os/$(OS_DIR) $(top_srcdir)/modules/http -EXPORT_DIRS_APR = $(APR_INCLUDEDIR) $(APU_INCLUDEDIR) - -# If export_files is a dependency here, but we remove it during this stage, -# when exports.c is generated, make will not detect that export_files is no -# longer here and deadlock. So, export_files can't be a dependency of -# delete-exports. -delete-exports: - @if test -f exports.c; then \ - if test -f export_files; then \ - files=`cat export_files`; \ - headers="`find $$files -newer exports.c`"; \ - if test -n "$$headers"; then \ - echo Found newer headers. Will rebuild exports.c.; \ - echo rm -f exports.c export_files; \ - rm -f exports.c export_files; \ - fi; \ - else \ - rm -f exports.c; \ - fi; \ - fi - -export_files: - tmp=export_files_unsorted.txt; \ - rm -f $$tmp && touch $$tmp; \ - for dir in $(EXPORT_DIRS); do \ - ls $$dir/*.h >> $$tmp; \ - done; \ - for dir in $(EXPORT_DIRS_APR); do \ - (ls $$dir/ap[ru].h $$dir/ap[ru]_*.h >> $$tmp 2>/dev/null); \ - done; \ - sort -u $$tmp > $@; \ - rm -f $$tmp - -exports.c: export_files - $(AWK) -f $(top_srcdir)/build/make_exports.awk `cat $?` > $@ - -export_vars.h: export_files - $(AWK) -f $(top_srcdir)/build/make_var_export.awk `cat $?` > $@ - -# Rule to make def file for OS/2 core dll -ApacheCoreOS2.def: exports.c export_vars.h $(top_srcdir)/os/$(OS_DIR)/core_header.def - cat $(top_srcdir)/os/$(OS_DIR)/core_header.def > $@ - $(CPP) $< $(ALL_CPPFLAGS) $(ALL_INCLUDES) | grep "ap_hack_" | sed -e 's/^.*[)]\(.*\);$$/ "\1"/' >> $@ - $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep "^[a-z]" | sed -e 's/^\(.*\)$$/ "\1"/' >> $@ - -# Rule to make exp file for AIX DSOs -httpd.exp: exports.c export_vars.h - @echo "#! ." > $@ - @echo "* This file was AUTOGENERATED at build time." >> $@ - @echo "* Please do not edit by hand." >> $@ - $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) exports.c | grep "ap_hack_" | grep -v apr_ | sed -e 's/^.*[)]\(.*\);$$/\1/' >> $@ - $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep -v apr_ | sed -e 's/^\#[^!]*//' | sed -e '/^$$/d' >> $@ diff --git a/rubbos/app/httpd-2.0.64/server/NWGNUmakefile b/rubbos/app/httpd-2.0.64/server/NWGNUmakefile deleted file mode 100644 index f2f6da75..00000000 --- a/rubbos/app/httpd-2.0.64/server/NWGNUmakefile +++ /dev/null @@ -1,251 +0,0 @@ -# -# Declare the sub-directories to be built here -# - -SUBDIRS = \ - ../build \ - $(EOLIST) - -# -# Get the 'head' of the build environment. This includes default targets and -# paths to tools -# - -include $(AP_WORK)\build\NWGNUhead.inc - -# -# build this level's files - -# -# These directories will be at the beginning of the include list, followed by -# INCDIRS -# -XINCDIRS += \ - $(NWOS) \ - $(APR)/include \ - $(AP_WORK)/include \ - $(APRUTIL)/include \ - $(EOLIST) - -# -# These flags will come after CFLAGS -# -XCFLAGS += \ - $(EOLIST) - -# -# These defines will come after DEFINES -# -XDEFINES += \ - $(EOLIST) - -# -# These flags will be added to the link.opt file -# -XLFLAGS += \ - $(EOLIST) - -# -# These values will be appended to the correct variables based on the value of -# RELEASE -# -ifeq "$(RELEASE)" "debug" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "noopt" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "release" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -# -# These are used by the link target if an NLM is being generated -# This is used by the link 'name' directive to name the nlm. If left blank -# TARGET_nlm (see below) will be used. -# -NLM_NAME = genchars - -# -# This is used by the link '-desc ' directive. -# If left blank, NLM_NAME will be used. -# -NLM_DESCRIPTION = Generate Test Characters - -# -# This is used by the '-threadname' directive. If left blank, -# NLM_NAME Thread will be used. -# -NLM_THREAD_NAME = genchars - -# -# If this is specified, it will override VERSION value in -# $(AP_WORK)\NWGNUNetWare.rul -# -NLM_VERSION = 1,0,0 - -# -# If this is specified, it will override the default of 64K -# -NLM_STACK_SIZE = 8192 - -# -# If this is specified it will be used by the link '-entry' directive -# -NLM_ENTRY_SYM =_LibCPrelude - -# -# If this is specified it will be used by the link '-exit' directive -# -NLM_EXIT_SYM =_LibCPostlude - -# -# If this is specified it will be used by the link '-check' directive -# -NLM_CHECK_SYM = - -# -# If this is specified it will be used by the link '-flags' directive -# -NLM_FLAGS = PSEUDOPREEMPTION - -# -# If this is specified it will be linked in with the XDCData option in the def -# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled -# by setting APACHE_UNIPROC in the environment -# -XDCDATA = - -# -# Declare all target files (you must add your files here) -# - -# -# If there is an NLM target, put it here -# -TARGET_nlm = \ -$(OBJDIR)/genchars.nlm \ - $(EOLIST) - -# -# If there is an LIB target, put it here -# -TARGET_lib = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the NLM target above. -# Paths must all use the '/' character -# -FILES_nlm_objs = \ - $(OBJDIR)/gen_test_char.o \ - $(EOLIST) - -# -# These are the LIB files needed to create the NLM target above. -# These will be added as a library command in the link.opt file. -# -FILES_nlm_libs = \ - libcpre.o \ - $(EOLIST) - -# -# These are the modules that the above NLM target depends on to load. -# These will be added as a module command in the link.opt file. -# -FILES_nlm_modules = \ - Libc \ - $(EOLIST) - -# -# If the nlm has a msg file, put it's path here -# -FILE_nlm_msg = - -# -# If the nlm has a hlp file put it's path here -# -FILE_nlm_hlp = - -# -# If this is specified, it will override $(NWOS)\copyright.txt. -# -FILE_nlm_copyright = - -# -# Any additional imports go here -# -FILES_nlm_Ximports = \ - @libc.imp \ - $(EOLIST) - -# -# Any symbols exported to here -# -FILES_nlm_exports = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the LIB target above. -# Paths must all use the '/' character -# -FILES_lib_objs = \ - $(EOLIST) - -# -# implement targets and dependancies (leave this section alone) -# - -libs :: $(OBJDIR) $(TARGET_lib) - -nlms :: libs $(TARGET_nlm) - -# -# Updated this target to create necessary directories and copy files to the -# correct place. -# -install :: nlms FORCE - -# -# Any specialized rules here -# - -# -# Include the 'tail' makefile that has targets that depend on variables defined -# in this makefile -# - -include $(AP_WORK)\build\NWGNUtail.inc - diff --git a/rubbos/app/httpd-2.0.64/server/buildmark.c b/rubbos/app/httpd-2.0.64/server/buildmark.c deleted file mode 100644 index a9cd6844..00000000 --- a/rubbos/app/httpd-2.0.64/server/buildmark.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ap_config.h" -#include "httpd.h" - -#if defined(__DATE__) && defined(__TIME__) -static const char server_built[] = __DATE__ " " __TIME__; -#else -static const char server_built[] = "unknown"; -#endif - -AP_DECLARE(const char *) ap_get_server_built() -{ - return server_built; -} diff --git a/rubbos/app/httpd-2.0.64/server/buildmark.lo b/rubbos/app/httpd-2.0.64/server/buildmark.lo deleted file mode 100644 index 5982051d..00000000 --- a/rubbos/app/httpd-2.0.64/server/buildmark.lo +++ /dev/null @@ -1,12 +0,0 @@ -# buildmark.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/buildmark.o' - -# Name of the non-PIC object. -non_pic_object='buildmark.o' - diff --git a/rubbos/app/httpd-2.0.64/server/buildmark.o b/rubbos/app/httpd-2.0.64/server/buildmark.o Binary files differdeleted file mode 100644 index 8dca2913..00000000 --- a/rubbos/app/httpd-2.0.64/server/buildmark.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/config.c b/rubbos/app/httpd-2.0.64/server/config.c deleted file mode 100644 index b3817be7..00000000 --- a/rubbos/app/httpd-2.0.64/server/config.c +++ /dev/null @@ -1,2045 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * http_config.c: once was auxillary functions for reading httpd's config - * file and converting filenames into a namespace - * - * Rob McCool - * - * Wall-to-wall rewrite for Apache... commands which are part of the - * server core can now be found next door in "http_core.c". Now contains - * general command loop, and functions which do bookkeeping for the new - * Apache config stuff (modules and configuration vectors). - * - * rst - * - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_portable.h" -#include "apr_file_io.h" -#include "apr_fnmatch.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_protocol.h" -#include "http_core.h" -#include "http_log.h" /* for errors in parse_htaccess */ -#include "http_request.h" /* for default_handler (see invoke_handler) */ -#include "http_main.h" -#include "http_vhost.h" -#include "util_cfgtree.h" -#include "mpm.h" - - -AP_DECLARE_DATA const char *ap_server_argv0 = NULL; - -AP_DECLARE_DATA const char *ap_server_root = NULL; - -AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL; -AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL; -AP_DECLARE_DATA apr_array_header_t *ap_server_config_defines = NULL; - -AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL; - -APR_HOOK_STRUCT( - APR_HOOK_LINK(header_parser) - APR_HOOK_LINK(pre_config) - APR_HOOK_LINK(post_config) - APR_HOOK_LINK(open_logs) - APR_HOOK_LINK(child_init) - APR_HOOK_LINK(handler) - APR_HOOK_LINK(quick_handler) - APR_HOOK_LINK(optional_fn_retrieve) -) - -AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser, - (request_rec *r), (r), OK, DECLINED) - -AP_IMPLEMENT_HOOK_RUN_ALL(int, pre_config, - (apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp), - (pconf, plog, ptemp), OK, DECLINED) - -AP_IMPLEMENT_HOOK_RUN_ALL(int, post_config, - (apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp, server_rec *s), - (pconf, plog, ptemp, s), OK, DECLINED) - -/* During the course of debugging I expanded this macro out, so - * rather than remove all the useful information there is in the - * following lines, I'm going to leave it here in case anyone - * else finds it useful. - * - * Ben has looked at it and thinks it correct :) - * -AP_DECLARE(int) ap_hook_post_config(ap_HOOK_post_config_t *pf, - const char * const *aszPre, - const char * const *aszSucc, - int nOrder) -{ - ap_LINK_post_config_t *pHook; - - if (!_hooks.link_post_config) { - _hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1, - sizeof(ap_LINK_post_config_t)); - apr_hook_sort_register("post_config", &_hooks.link_post_config); - } - - pHook = apr_array_push(_hooks.link_post_config); - pHook->pFunc = pf; - pHook->aszPredecessors = aszPre; - pHook->aszSuccessors = aszSucc; - pHook->nOrder = nOrder; - pHook->szName = apr_hook_debug_current; - - if (apr_hook_debug_enabled) - apr_hook_debug_show("post_config", aszPre, aszSucc); -} - -AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void) { - return _hooks.link_post_config; -} - -AP_DECLARE(int) ap_run_post_config(apr_pool_t *pconf, - apr_pool_t *plog, - apr_pool_t *ptemp, - server_rec *s) -{ - ap_LINK_post_config_t *pHook; - int n; - - if(!_hooks.link_post_config) - return; - - pHook = (ap_LINK_post_config_t *)_hooks.link_post_config->elts; - for (n = 0; n < _hooks.link_post_config->nelts; ++n) - pHook[n].pFunc (pconf, plog, ptemp, s); -} - */ - -AP_IMPLEMENT_HOOK_RUN_ALL(int, open_logs, - (apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp, server_rec *s), - (pconf, plog, ptemp, s), OK, DECLINED) - -AP_IMPLEMENT_HOOK_VOID(child_init, - (apr_pool_t *pchild, server_rec *s), - (pchild, s)) - -AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r), - (r), DECLINED) - -AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup), - (r, lookup), DECLINED) - -AP_IMPLEMENT_HOOK_VOID(optional_fn_retrieve, (void), ()) - -/**************************************************************** - * - * We begin with the functions which deal with the linked list - * of modules which control just about all of the server operation. - */ - -/* total_modules is the number of modules that have been linked - * into the server. - */ -static int total_modules = 0; - -/* dynamic_modules is the number of modules that have been added - * after the pre-loaded ones have been set up. It shouldn't be larger - * than DYNAMIC_MODULE_LIMIT. - */ -static int dynamic_modules = 0; - -AP_DECLARE_DATA module *ap_top_module = NULL; -AP_DECLARE_DATA module **ap_loaded_modules=NULL; - -typedef int (*handler_func)(request_rec *); -typedef void *(*dir_maker_func)(apr_pool_t *, char *); -typedef void *(*merger_func)(apr_pool_t *, void *, void *); - -/* maximum nesting level for config directories */ -#ifndef AP_MAX_INCLUDE_DIR_DEPTH -#define AP_MAX_INCLUDE_DIR_DEPTH (128) -#endif - -/* Dealing with config vectors. These are associated with per-directory, - * per-server, and per-request configuration, and have a void* pointer for - * each modules. The nature of the structure pointed to is private to the - * module in question... the core doesn't (and can't) know. However, there - * are defined interfaces which allow it to create instances of its private - * per-directory and per-server structures, and to merge the per-directory - * structures of a directory and its subdirectory (producing a new one in - * which the defaults applying to the base directory have been properly - * overridden). - */ - -static ap_conf_vector_t *create_empty_config(apr_pool_t *p) -{ - void *conf_vector = apr_pcalloc(p, sizeof(void *) * - (total_modules + DYNAMIC_MODULE_LIMIT)); - return conf_vector; -} - -static ap_conf_vector_t *create_default_per_dir_config(apr_pool_t *p) -{ - void **conf_vector = apr_pcalloc(p, sizeof(void *) * - (total_modules + DYNAMIC_MODULE_LIMIT)); - module *modp; - - for (modp = ap_top_module; modp; modp = modp->next) { - dir_maker_func df = modp->create_dir_config; - - if (df) - conf_vector[modp->module_index] = (*df)(p, NULL); - } - - return (ap_conf_vector_t *)conf_vector; -} - -AP_CORE_DECLARE(ap_conf_vector_t *) ap_merge_per_dir_configs(apr_pool_t *p, - ap_conf_vector_t *base, - ap_conf_vector_t *new_conf) -{ - void **conf_vector = apr_palloc(p, sizeof(void *) * total_modules); - void **base_vector = (void **)base; - void **new_vector = (void **)new_conf; - module *modp; - - for (modp = ap_top_module; modp; modp = modp->next) { - int i = modp->module_index; - - if (!new_vector[i]) { - conf_vector[i] = base_vector[i]; - } - else { - merger_func df = modp->merge_dir_config; - if (df && base_vector[i]) { - conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]); - } - else - conf_vector[i] = new_vector[i]; - } - } - - return (ap_conf_vector_t *)conf_vector; -} - -static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s) -{ - void **conf_vector = apr_pcalloc(p, sizeof(void *) * - (total_modules + DYNAMIC_MODULE_LIMIT)); - module *modp; - - for (modp = ap_top_module; modp; modp = modp->next) { - if (modp->create_server_config) - conf_vector[modp->module_index] = (*modp->create_server_config)(p, s); - } - - return (ap_conf_vector_t *)conf_vector; -} - -static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base, - ap_conf_vector_t *virt) -{ - /* Can reuse the 'virt' vector for the spine of it, since we don't - * have to deal with the moral equivalent of .htaccess files here... - */ - - void **base_vector = (void **)base; - void **virt_vector = (void **)virt; - module *modp; - - for (modp = ap_top_module; modp; modp = modp->next) { - merger_func df = modp->merge_server_config; - int i = modp->module_index; - - if (!virt_vector[i]) - virt_vector[i] = base_vector[i]; - else if (df) - virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]); - } -} - -AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_request_config(apr_pool_t *p) -{ - return create_empty_config(p); -} - -AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_conn_config(apr_pool_t *p) -{ - return create_empty_config(p); -} - -AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p) -{ - return create_empty_config(p); -} - -static int ap_invoke_filter_init(ap_filter_t *filters) -{ - while (filters) { - if (filters->frec->filter_init_func) { - int result = filters->frec->filter_init_func(filters); - if (result != OK) { - return result; - } - } - filters = filters->next; - } - return OK; -} - -AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r) -{ - const char *handler; - const char *p; - int result; - const char *old_handler = r->handler; - - /* - * The new insert_filter stage makes the most sense here. We only use - * it when we are going to run the request, so we must insert filters - * if any are available. Since the goal of this phase is to allow all - * modules to insert a filter if they want to, this filter returns - * void. I just can't see any way that this filter can reasonably - * fail, either your modules inserts something or it doesn't. rbb - */ - ap_run_insert_filter(r); - - /* Before continuing, allow each filter that is in the two chains to - * run their init function to let them do any magic before we could - * start generating data. - */ - result = ap_invoke_filter_init(r->input_filters); - if (result != OK) { - return result; - } - result = ap_invoke_filter_init(r->output_filters); - if (result != OK) { - return result; - } - - if (!r->handler) { - handler = r->content_type ? r->content_type : ap_default_type(r); - if ((p=ap_strchr_c(handler, ';')) != NULL) { - char *new_handler = (char *)apr_pmemdup(r->pool, handler, - p - handler + 1); - char *p2 = new_handler + (p - handler); - handler = new_handler; - - /* MIME type arguments */ - while (p2 > handler && p2[-1] == ' ') - --p2; /* strip trailing spaces */ - - *p2='\0'; - } - - r->handler = handler; - } - - result = ap_run_handler(r); - - r->handler = old_handler; - - if (result == DECLINED && r->handler && r->filename) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "handler \"%s\" not found for: %s", r->handler, r->filename); - } - - return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result; -} - -AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method) -{ - int methnum; - - methnum = ap_method_number_of(method); - - /* - * A method number either hardcoded into apache or - * added by a module and registered. - */ - if (methnum != M_INVALID) { - return (cmd->limited & (AP_METHOD_BIT << methnum)) ? 1 : 0; - } - - return 0; /* not found */ -} - -AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p) -{ - if (m->register_hooks) { - if (getenv("SHOW_HOOKS")) { - printf("Registering hooks for %s\n", m->name); - apr_hook_debug_enabled = 1; - } - - apr_hook_debug_current = m->name; - m->register_hooks(p); - } -} - -/* One-time setup for precompiled modules --- NOT to be done on restart */ - -AP_DECLARE(void) ap_add_module(module *m, apr_pool_t *p) -{ - /* This could be called from an AddModule httpd.conf command, - * after the file has been linked and the module structure within it - * teased out... - */ - - if (m->version != MODULE_MAGIC_NUMBER_MAJOR) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s: module \"%s\" is not compatible with this " - "version of Apache (found %d, need %d).", - ap_server_argv0, m->name, m->version, - MODULE_MAGIC_NUMBER_MAJOR); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please contact the vendor for the correct version."); - exit(1); - } - - if (m->next == NULL) { - m->next = ap_top_module; - ap_top_module = m; - } - - if (m->module_index == -1) { - m->module_index = total_modules++; - dynamic_modules++; - - if (dynamic_modules > DYNAMIC_MODULE_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s: module \"%s\" could not be loaded, because" - " the dynamic", ap_server_argv0, m->name); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "module limit was reached. Please increase " - "DYNAMIC_MODULE_LIMIT and recompile."); - exit(1); - } - } - - /* Some C compilers put a complete path into __FILE__, but we want - * only the filename (e.g. mod_includes.c). So check for path - * components (Unix and DOS), and remove them. - */ - - if (ap_strrchr_c(m->name, '/')) - m->name = 1 + ap_strrchr_c(m->name, '/'); - - if (ap_strrchr_c(m->name, '\\')) - m->name = 1 + ap_strrchr_c(m->name, '\\'); - -#ifdef _OSD_POSIX - /* __FILE__ = - * "*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)" - */ - - /* We cannot fix the string in-place, because it's const */ - if (m->name[strlen(m->name)-1] == ')') { - char *tmp = strdup(m->name); /* FIXME: memory leak, albeit a small one */ - tmp[strlen(tmp)-1] = '\0'; - m->name = tmp; - } -#endif /*_OSD_POSIX*/ - - /* FIXME: is this the right place to call this? - * It doesn't appear to be - */ - ap_register_hooks(m, p); -} - -/* - * remove_module undoes what add_module did. There are some caveats: - * when the module is removed, its slot is lost so all the current - * per-dir and per-server configurations are invalid. So we should - * only ever call this function when you are invalidating almost - * all our current data. I.e. when doing a restart. - */ - -AP_DECLARE(void) ap_remove_module(module *m) -{ - module *modp; - - modp = ap_top_module; - if (modp == m) { - /* We are the top module, special case */ - ap_top_module = modp->next; - m->next = NULL; - } - else { - /* Not the top module, find use. When found modp will - * point to the module _before_ us in the list - */ - - while (modp && modp->next != m) { - modp = modp->next; - } - - if (!modp) { - /* Uh-oh, this module doesn't exist */ - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "Cannot remove module %s: not found in module list", - m->name); - return; - } - - /* Eliminate us from the module list */ - modp->next = modp->next->next; - } - - m->module_index = -1; /* simulate being unloaded, should - * be unnecessary */ - dynamic_modules--; - total_modules--; -} - -AP_DECLARE(void) ap_add_loaded_module(module *mod, apr_pool_t *p) -{ - module **m; - - /* - * Add module pointer to top of chained module list - */ - ap_add_module(mod, p); - - /* - * And module pointer to list of loaded modules - * - * Notes: 1. ap_add_module() would already complain if no more space - * exists for adding a dynamically loaded module - * 2. ap_add_module() accepts double inclusion, so we have - * to accept this, too. - */ - for (m = ap_loaded_modules; *m != NULL; m++) - ; - *m++ = mod; - *m = NULL; -} - -AP_DECLARE(void) ap_remove_loaded_module(module *mod) -{ - module **m; - module **m2; - int done; - - /* - * Remove module pointer from chained module list - */ - ap_remove_module(mod); - - /* - * Remove module pointer from list of loaded modules - * - * Note: 1. We cannot determine if the module was successfully - * removed by ap_remove_module(). - * 2. We have not to complain explicity when the module - * is not found because ap_remove_module() did it - * for us already. - */ - for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) { - if (*m2 == mod && done == 0) - done = 1; - else - *m++ = *m2; - } - - *m = NULL; -} - -AP_DECLARE(void) ap_setup_prelinked_modules(process_rec *process) -{ - module **m; - module **m2; - - apr_hook_global_pool=process->pconf; - - /* - * Initialise total_modules variable and module indices - */ - total_modules = 0; - for (m = ap_preloaded_modules; *m != NULL; m++) - (*m)->module_index = total_modules++; - - /* - * Initialise list of loaded modules - */ - ap_loaded_modules = (module **)apr_palloc(process->pool, - sizeof(module *) * (total_modules + DYNAMIC_MODULE_LIMIT + 1)); - - if (ap_loaded_modules == NULL) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Ouch! Out of memory in ap_setup_prelinked_modules()!"); - } - - for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; ) - *m2++ = *m++; - - *m2 = NULL; - - /* - * Initialize chain of linked (=activate) modules - */ - for (m = ap_prelinked_modules; *m != NULL; m++) - ap_add_module(*m, process->pconf); - - apr_hook_sort_all(); -} - -AP_DECLARE(const char *) ap_find_module_name(module *m) -{ - return m->name; -} - -AP_DECLARE(module *) ap_find_linked_module(const char *name) -{ - module *modp; - - for (modp = ap_top_module; modp; modp = modp->next) { - if (strcmp(modp->name, name) == 0) - return modp; - } - - return NULL; -} - -/* Add a named module. Returns 1 if module found, 0 otherwise. */ -AP_DECLARE(int) ap_add_named_module(const char *name, apr_pool_t *p) -{ - module *modp; - int i = 0; - - for (modp = ap_loaded_modules[i]; modp; modp = ap_loaded_modules[++i]) { - if (strcmp(modp->name, name) == 0) { - /* Only add modules that are not already enabled. */ - if (modp->next == NULL) { - ap_add_module(modp, p); - } - - return 1; - } - } - - return 0; -} - -/***************************************************************** - * - * Resource, access, and .htaccess config files now parsed by a common - * command loop. - * - * Let's begin with the basics; parsing the line and - * invoking the function... - */ - -static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms, - void *mconfig, const char *args) -{ - char *w, *w2, *w3; - const char *errmsg = NULL; - - if ((parms->override & cmd->req_override) == 0) - return apr_pstrcat(parms->pool, cmd->name, " not allowed here", NULL); - - parms->info = cmd->cmd_data; - parms->cmd = cmd; - - switch (cmd->args_how) { - case RAW_ARGS: -#ifdef RESOLVE_ENV_PER_TOKEN - args = ap_resolve_env(parms->pool,args); -#endif - return cmd->AP_RAW_ARGS(parms, mconfig, args); - - case NO_ARGS: - if (*args != 0) - return apr_pstrcat(parms->pool, cmd->name, " takes no arguments", - NULL); - - return cmd->AP_NO_ARGS(parms, mconfig); - - case TAKE1: - w = ap_getword_conf(parms->pool, &args); - - if (*w == '\0' || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, " takes one argument", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE1(parms, mconfig, w); - - case TAKE2: - w = ap_getword_conf(parms->pool, &args); - w2 = ap_getword_conf(parms->pool, &args); - - if (*w == '\0' || *w2 == '\0' || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, " takes two arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE2(parms, mconfig, w, w2); - - case TAKE12: - w = ap_getword_conf(parms->pool, &args); - w2 = ap_getword_conf(parms->pool, &args); - - if (*w == '\0' || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL); - - case TAKE3: - w = ap_getword_conf(parms->pool, &args); - w2 = ap_getword_conf(parms->pool, &args); - w3 = ap_getword_conf(parms->pool, &args); - - if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, " takes three arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); - - case TAKE23: - w = ap_getword_conf(parms->pool, &args); - w2 = ap_getword_conf(parms->pool, &args); - w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL; - - if (*w == '\0' || *w2 == '\0' || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, - " takes two or three arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); - - case TAKE123: - w = ap_getword_conf(parms->pool, &args); - w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL; - w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL; - - if (*w == '\0' || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, - " takes one, two or three arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); - - case TAKE13: - w = ap_getword_conf(parms->pool, &args); - w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL; - w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL; - - if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0) - return apr_pstrcat(parms->pool, cmd->name, - " takes one or three arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); - - case ITERATE: - while (*(w = ap_getword_conf(parms->pool, &args)) != '\0') { - - errmsg = cmd->AP_TAKE1(parms, mconfig, w); - - if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0) - return errmsg; - } - - return errmsg; - - case ITERATE2: - w = ap_getword_conf(parms->pool, &args); - - if (*w == '\0' || *args == 0) - return apr_pstrcat(parms->pool, cmd->name, - " requires at least two arguments", - cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - - while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0') { - - errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2); - - if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0) - return errmsg; - } - - return errmsg; - - case FLAG: - w = ap_getword_conf(parms->pool, &args); - - if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off"))) - return apr_pstrcat(parms->pool, cmd->name, " must be On or Off", - NULL); - - return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0); - - default: - return apr_pstrcat(parms->pool, cmd->name, - " is improperly configured internally (server bug)", - NULL); - } -} - -AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name, - const command_rec *cmds) -{ - while (cmds->name) { - if (!strcasecmp(name, cmds->name)) - return cmds; - - ++cmds; - } - - return NULL; -} - -AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules( - const char *cmd_name, module **mod) -{ - const command_rec *cmdp; - module *modp; - - for (modp = *mod; modp; modp = modp->next) { - if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) { - *mod = modp; - return cmdp; - } - } - - return NULL; -} - -AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server, - ap_conf_vector_t *section_vector, - const char *section, - module *mod, apr_pool_t *pconf) -{ - void *section_config = ap_get_module_config(section_vector, mod); - void *server_config = ap_get_module_config(server->module_config, mod); - - if (!section_config && mod->create_dir_config) { - /* ### need to fix the create_dir_config functions' prototype... */ - section_config = (*mod->create_dir_config)(pconf, (char *)section); - ap_set_module_config(section_vector, mod, section_config); - } - - if (!server_config && mod->create_server_config) { - server_config = (*mod->create_server_config)(pconf, server); - ap_set_module_config(server->module_config, mod, server_config); - } - - return section_config; -} - -static const char *execute_now(char *cmd_line, const char *args, - cmd_parms *parms, - apr_pool_t *p, apr_pool_t *ptemp, - ap_directive_t **sub_tree, - ap_directive_t *parent); - -static const char *ap_build_config_sub(apr_pool_t *p, apr_pool_t *temp_pool, - const char *l, cmd_parms *parms, - ap_directive_t **current, - ap_directive_t **curr_parent, - ap_directive_t **conftree) -{ - const char *retval = NULL; - const char *args; - char *cmd_name; - ap_directive_t *newdir; - module *mod = ap_top_module; - const command_rec *cmd; - - if (*l == '#' || *l == '\0') - return NULL; - -#if RESOLVE_ENV_PER_TOKEN - args = l; -#else - args = ap_resolve_env(temp_pool, l); -#endif - - cmd_name = ap_getword_conf(p, &args); - if (*cmd_name == '\0') { - /* Note: this branch should not occur. An empty line should have - * triggered the exit further above. - */ - return NULL; - } - - if (cmd_name[1] != '/') { - char *lastc = cmd_name + strlen(cmd_name) - 1; - if (*lastc == '>') { - *lastc = '\0' ; - } - if (cmd_name[0] == '<' && *args == '\0') { - args = ">"; - } - } - - newdir = apr_pcalloc(p, sizeof(ap_directive_t)); - newdir->filename = parms->config_file->name; - newdir->line_num = parms->config_file->line_number; - newdir->directive = cmd_name; - newdir->args = apr_pstrdup(p, args); - - if ((cmd = ap_find_command_in_modules(cmd_name, &mod)) != NULL) { - if (cmd->req_override & EXEC_ON_READ) { - ap_directive_t *sub_tree = NULL; - - parms->err_directive = newdir; - retval = execute_now(cmd_name, args, parms, p, temp_pool, - &sub_tree, *curr_parent); - if (*current) { - (*current)->next = sub_tree; - } - else { - *current = sub_tree; - if (*curr_parent) { - (*curr_parent)->first_child = (*current); - } - if (*current) { - (*current)->parent = (*curr_parent); - } - } - if (*current) { - if (!*conftree) { - /* Before walking *current to the end of the list, - * set the head to *current. - */ - *conftree = *current; - } - while ((*current)->next != NULL) { - (*current) = (*current)->next; - (*current)->parent = (*curr_parent); - } - } - return retval; - } - } - - if (cmd_name[0] == '<') { - if (cmd_name[1] != '/') { - (*current) = ap_add_node(curr_parent, *current, newdir, 1); - } - else if (*curr_parent == NULL) { - parms->err_directive = newdir; - return apr_pstrcat(p, cmd_name, - " without matching <", cmd_name + 2, - " section", NULL); - } - else { - char *bracket = cmd_name + strlen(cmd_name) - 1; - - if (*bracket != '>') { - parms->err_directive = newdir; - return apr_pstrcat(p, cmd_name, - "> directive missing closing '>'", NULL); - } - - *bracket = '\0'; - - if (strcasecmp(cmd_name + 2, - (*curr_parent)->directive + 1) != 0) { - parms->err_directive = newdir; - return apr_pstrcat(p, "Expected </", - (*curr_parent)->directive + 1, "> but saw ", - cmd_name, ">", NULL); - } - - *bracket = '>'; - - /* done with this section; move up a level */ - *current = *curr_parent; - *curr_parent = (*current)->parent; - } - } - else { - *current = ap_add_node(curr_parent, *current, newdir, 0); - } - - return retval; -} - -AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p, - apr_pool_t *temp_pool, - cmd_parms *parms, - ap_directive_t **current, - ap_directive_t **curr_parent, - char *orig_directive) -{ - char *l; - char *bracket; - const char *retval; - ap_directive_t *sub_tree = NULL; - - /* Since this function can be called recursively, allocate - * the temporary 8k string buffer from the temp_pool rather - * than the stack to avoid over-running a fixed length stack. - */ - l = apr_palloc(temp_pool, MAX_STRING_LEN); - - bracket = apr_pstrcat(p, orig_directive + 1, ">", NULL); - while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) { - if (!memcmp(l, "</", 2) - && (strcasecmp(l + 2, bracket) == 0) - && (*curr_parent == NULL)) { - break; - } - retval = ap_build_config_sub(p, temp_pool, l, parms, current, - curr_parent, &sub_tree); - if (retval != NULL) - return retval; - - if (sub_tree == NULL && curr_parent != NULL) { - sub_tree = *curr_parent; - } - - if (sub_tree == NULL && current != NULL) { - sub_tree = *current; - } - } - - *current = sub_tree; - return NULL; -} - -static const char *ap_walk_config_sub(const ap_directive_t *current, - cmd_parms *parms, - ap_conf_vector_t *section_vector) -{ - module *mod = ap_top_module; - - while (1) { - const command_rec *cmd; - - if (!(cmd = ap_find_command_in_modules(current->directive, &mod))) { - parms->err_directive = current; - return apr_pstrcat(parms->pool, "Invalid command '", - current->directive, - "', perhaps mis-spelled or defined by a module " - "not included in the server configuration", - NULL); - } - else { - void *dir_config = ap_set_config_vectors(parms->server, - section_vector, - parms->path, - mod, - parms->pool); - const char *retval; - - /* Once was enough? */ - if (cmd->req_override & EXEC_ON_READ) { - return NULL; - } - - retval = invoke_cmd(cmd, parms, dir_config, current->args); - if (retval == NULL) { - return NULL; - } - - if (strcmp(retval, DECLINE_CMD) != 0) { - /* If the directive in error has already been set, don't - * replace it. Otherwise, an error inside a container - * will be reported as occuring on the first line of the - * container. - */ - if (!parms->err_directive) { - parms->err_directive = current; - } - - return retval; - } - - mod = mod->next; /* Next time around, skip this one */ - } - } - /* NOTREACHED */ -} - -AP_DECLARE(const char *) ap_walk_config(ap_directive_t *current, - cmd_parms *parms, - ap_conf_vector_t *section_vector) -{ - ap_conf_vector_t *oldconfig = parms->context; - - parms->context = section_vector; - - /* scan through all directives, executing each one */ - for (; current != NULL; current = current->next) { - const char *errmsg; - - parms->directive = current; - - /* actually parse the command and execute the correct function */ - errmsg = ap_walk_config_sub(current, parms, section_vector); - if (errmsg != NULL) { - /* restore the context (just in case) */ - parms->context = oldconfig; - return errmsg; - } - } - - parms->context = oldconfig; - return NULL; -} - -AP_DECLARE(const char *) ap_build_config(cmd_parms *parms, - apr_pool_t *p, apr_pool_t *temp_pool, - ap_directive_t **conftree) -{ - ap_directive_t *current = *conftree; - ap_directive_t *curr_parent = NULL; - char *l = apr_palloc (temp_pool, MAX_STRING_LEN); - const char *errmsg; - - if (current != NULL) { - while (current->next) { - current = current->next; - } - } - - while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) { - errmsg = ap_build_config_sub(p, temp_pool, l, parms, - ¤t, &curr_parent, conftree); - if (errmsg != NULL) - return errmsg; - - if (*conftree == NULL && curr_parent != NULL) { - *conftree = curr_parent; - } - - if (*conftree == NULL && current != NULL) { - *conftree = current; - } - } - - if (curr_parent != NULL) { - errmsg = ""; - - while (curr_parent != NULL) { - errmsg = apr_psprintf(p, "%s%s%s:%u: %s> was not closed.", - errmsg, - *errmsg == '\0' ? "" : APR_EOL_STR, - curr_parent->filename, - curr_parent->line_num, - curr_parent->directive); - - parms->err_directive = curr_parent; - curr_parent = curr_parent->parent; - } - - return errmsg; - } - - return NULL; -} - -/* - * Generic command functions... - */ - -AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd, - void *struct_ptr, - const char *arg) -{ - int offset = (int)(long)cmd->info; - - *(const char **)((char *)struct_ptr + offset) = arg; - - return NULL; -} - -AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd, - void *struct_ptr, - const char *arg) -{ - char *endptr; - char *error_str = NULL; - int offset = (int)(long)cmd->info; - - *(int *)((char*)struct_ptr + offset) = strtol(arg, &endptr, 10); - - if ((*arg == '\0') || (*endptr != '\0')) { - error_str = apr_psprintf(cmd->pool, - "Invalid value for directive %s, expected integer", - cmd->directive->directive); - } - - return error_str; -} - -AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd, - void *struct_ptr, - const char *arg_) -{ - char *arg = apr_pstrdup(cmd->pool,arg_); - int offset = (int)(long)cmd->info; - - ap_str_tolower(arg); - *(char **)((char *)struct_ptr + offset) = arg; - - return NULL; -} - -AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd, - void *struct_ptr_v, int arg) -{ - int offset = (int)(long)cmd->info; - char *struct_ptr = (char *)struct_ptr_v; - - *(int *)(struct_ptr + offset) = arg ? 1 : 0; - - return NULL; -} - -AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_ptr, - const char *arg) -{ - /* Prepend server_root to relative arg. - * This allows most args to be independent of server_root, - * so the server can be moved or mirrored with less pain. - */ - const char *path; - int offset = (int)(long)cmd->info; - - path = ap_server_root_relative(cmd->pool, arg); - - if (!path) { - return apr_pstrcat(cmd->pool, "Invalid file path ", - arg, NULL); - } - - *(const char **) ((char*)struct_ptr + offset) = path; - - return NULL; -} - -AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd, - void *struct_ptr, - const char *arg) -{ - return cmd->cmd->errmsg; -} - -/***************************************************************** - * - * Reading whole config files... - */ - -static cmd_parms default_parms = -{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - -AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file) -{ - char *newpath = NULL; - apr_status_t rv; - rv = apr_filepath_merge(&newpath, ap_server_root, file, - APR_FILEPATH_TRUENAME, p); - if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv) - || APR_STATUS_IS_ENOENT(rv) - || APR_STATUS_IS_ENOTDIR(rv))) { - return newpath; - } - else { - return NULL; - } -} - -AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive) -{ - char l[MAX_STRING_LEN]; - const char *args; - char *cmd_name; - - while(!(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) { -#if RESOLVE_ENV_PER_TOKEN - args = l; -#else - args = ap_resolve_env(cmd->temp_pool, l); -#endif - - cmd_name = ap_getword_conf(cmd->pool, &args); - if (cmd_name[0] == '<') { - if (cmd_name[1] == '/') { - cmd_name[strlen(cmd_name) - 1] = '\0'; - - if (strcasecmp(cmd_name + 2, directive + 1) != 0) { - return apr_pstrcat(cmd->pool, "Expected </", - directive + 1, "> but saw ", - cmd_name, ">", NULL); - } - - return NULL; /* found end of container */ - } - else { - const char *msg; - - if (*args == '\0' && cmd_name[strlen(cmd_name) - 1] == '>') { - cmd_name[strlen(cmd_name) - 1] = '\0'; - } - - if ((msg = ap_soak_end_container(cmd, cmd_name)) != NULL) { - return msg; - } - } - } - } - - return apr_pstrcat(cmd->pool, "Expected </", - directive + 1, "> before end of configuration", - NULL); -} - -static const char *execute_now(char *cmd_line, const char *args, - cmd_parms *parms, - apr_pool_t *p, apr_pool_t *ptemp, - ap_directive_t **sub_tree, - ap_directive_t *parent) -{ - module *mod = ap_top_module; - const command_rec *cmd; - - if (!(cmd = ap_find_command_in_modules(cmd_line, &mod))) { - return apr_pstrcat(parms->pool, "Invalid command '", - cmd_line, - "', perhaps mis-spelled or defined by a module " - "not included in the server configuration", - NULL); - } - else { - return invoke_cmd(cmd, parms, sub_tree, args); - } -} - -/* This structure and the following functions are needed for the - * table-based config file reading. They are passed to the - * cfg_open_custom() routine. - */ - -/* Structure to be passed to cfg_open_custom(): it contains an - * index which is incremented from 0 to nelts on each call to - * cfg_getline() (which in turn calls arr_elts_getstr()) - * and an apr_array_header_t pointer for the string array. - */ -typedef struct { - apr_array_header_t *array; - int curr_idx; -} arr_elts_param_t; - - -/* arr_elts_getstr() returns the next line from the string array. */ -static void *arr_elts_getstr(void *buf, size_t bufsiz, void *param) -{ - arr_elts_param_t *arr_param = (arr_elts_param_t *)param; - - /* End of array reached? */ - if (++arr_param->curr_idx > arr_param->array->nelts) - return NULL; - - /* return the line */ - apr_cpystrn(buf, - ((char **)arr_param->array->elts)[arr_param->curr_idx - 1], - bufsiz); - - return buf; -} - - -/* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */ -static int arr_elts_close(void *param) -{ - arr_elts_param_t *arr_param = (arr_elts_param_t *)param; - - arr_param->curr_idx = arr_param->array->nelts; - - return 0; -} - -static void process_command_config(server_rec *s, apr_array_header_t *arr, - ap_directive_t **conftree, apr_pool_t *p, - apr_pool_t *ptemp) -{ - const char *errmsg; - cmd_parms parms; - arr_elts_param_t arr_parms; - - arr_parms.curr_idx = 0; - arr_parms.array = arr; - - parms = default_parms; - parms.pool = p; - parms.temp_pool = ptemp; - parms.server = s; - parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); - - parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives", - &arr_parms, NULL, - arr_elts_getstr, arr_elts_close); - - errmsg = ap_build_config(&parms, p, ptemp, conftree); - if (errmsg) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Syntax error in -C/-c directive:"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s", errmsg); - exit(1); - } - - ap_cfg_closefile(parms.config_file); -} - -typedef struct { - char *fname; -} fnames; - -static int fname_alphasort(const void *fn1, const void *fn2) -{ - const fnames *f1 = fn1; - const fnames *f2 = fn2; - - return strcmp(f1->fname,f2->fname); -} - -static void process_resource_config_nofnmatch(server_rec *s, const char *fname, - ap_directive_t **conftree, - apr_pool_t *p, - apr_pool_t *ptemp, - unsigned depth) -{ - cmd_parms parms; - ap_configfile_t *cfp; - const char *errmsg; - - if (ap_is_directory(p, fname)) { - apr_dir_t *dirp; - apr_finfo_t dirent; - int current; - apr_array_header_t *candidates = NULL; - fnames *fnew; - apr_status_t rv; - char errmsg[120], *path = apr_pstrdup(p, fname); - - if (++depth > AP_MAX_INCLUDE_DIR_DEPTH) { - fprintf(stderr, "%s: Directory %s exceeds the maximum include " - "directory nesting level of %u. You have probably a " - "recursion somewhere.\n", ap_server_argv0, path, - AP_MAX_INCLUDE_DIR_DEPTH); - exit(1); - } - - /* - * first course of business is to grok all the directory - * entries here and store 'em away. Recall we need full pathnames - * for this. - */ - rv = apr_dir_open(&dirp, path, p); - if (rv != APR_SUCCESS) { - fprintf(stderr, "%s: could not open config directory %s: %s\n", - ap_server_argv0, path, - apr_strerror(rv, errmsg, sizeof errmsg)); - exit(1); - } - - candidates = apr_array_make(p, 1, sizeof(fnames)); - while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { - /* strip out '.' and '..' */ - if (strcmp(dirent.name, ".") - && strcmp(dirent.name, "..")) { - fnew = (fnames *) apr_array_push(candidates); - fnew->fname = ap_make_full_path(p, path, dirent.name); - } - } - - apr_dir_close(dirp); - if (candidates->nelts != 0) { - qsort((void *) candidates->elts, candidates->nelts, - sizeof(fnames), fname_alphasort); - - /* - * Now recurse these... we handle errors and subdirectories - * via the recursion, which is nice - */ - for (current = 0; current < candidates->nelts; ++current) { - fnew = &((fnames *) candidates->elts)[current]; - process_resource_config_nofnmatch(s, fnew->fname, conftree, p, - ptemp, depth); - } - } - - return; - } - - /* GCC's initialization extensions are soooo nice here... */ - parms = default_parms; - parms.pool = p; - parms.temp_pool = ptemp; - parms.server = s; - parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); - - if (ap_pcfg_openfile(&cfp, p, fname) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s: could not open document config file %s", - ap_server_argv0, fname); - exit(1); - } - - parms.config_file = cfp; - - errmsg = ap_build_config(&parms, p, ptemp, conftree); - - if (errmsg != NULL) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Syntax error on line %d of %s:", - parms.err_directive->line_num, - parms.err_directive->filename); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s", errmsg); - exit(1); - } - - ap_cfg_closefile(cfp); - - return; -} - -AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, - ap_directive_t **conftree, - apr_pool_t *p, - apr_pool_t *ptemp) -{ - /* XXX: lstat() won't work on the wildcard pattern... - */ - - /* don't require conf/httpd.conf if we have a -C or -c switch */ - if ((ap_server_pre_read_config->nelts - || ap_server_post_read_config->nelts) - && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) { - apr_finfo_t finfo; - - if (apr_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS) - return; - } - - if (!apr_fnmatch_test(fname)) { - process_resource_config_nofnmatch(s, fname, conftree, p, ptemp, 0); - } - else { - apr_dir_t *dirp; - apr_finfo_t dirent; - int current; - apr_array_header_t *candidates = NULL; - fnames *fnew; - apr_status_t rv; - char errmsg[120], *path = apr_pstrdup(p, fname), *pattern = NULL; - - pattern = ap_strrchr(path, '/'); - - AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */ - - *pattern++ = '\0'; - - if (apr_fnmatch_test(path)) { - fprintf(stderr, "%s: wildcard patterns not allowed in Include " - "%s\n", ap_server_argv0, fname); - exit(1); - } - - if (!ap_is_directory(p, path)){ - fprintf(stderr, "%s: Include directory '%s' not found", - ap_server_argv0, path); - exit(1); - } - - if (!apr_fnmatch_test(pattern)) { - fprintf(stderr, "%s: must include a wildcard pattern " - "for Include %s\n", ap_server_argv0, fname); - exit(1); - } - - /* - * first course of business is to grok all the directory - * entries here and store 'em away. Recall we need full pathnames - * for this. - */ - rv = apr_dir_open(&dirp, path, p); - if (rv != APR_SUCCESS) { - fprintf(stderr, "%s: could not open config directory %s: %s\n", - ap_server_argv0, path, - apr_strerror(rv, errmsg, sizeof errmsg)); - exit(1); - } - - candidates = apr_array_make(p, 1, sizeof(fnames)); - while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { - /* strip out '.' and '..' */ - if (strcmp(dirent.name, ".") - && strcmp(dirent.name, "..") - && (apr_fnmatch(pattern, dirent.name, - FNM_PERIOD) == APR_SUCCESS)) { - fnew = (fnames *) apr_array_push(candidates); - fnew->fname = ap_make_full_path(p, path, dirent.name); - } - } - - apr_dir_close(dirp); - if (candidates->nelts != 0) { - qsort((void *) candidates->elts, candidates->nelts, - sizeof(fnames), fname_alphasort); - - /* - * Now recurse these... we handle errors and subdirectories - * via the recursion, which is nice - */ - for (current = 0; current < candidates->nelts; ++current) { - fnew = &((fnames *) candidates->elts)[current]; - process_resource_config_nofnmatch(s, fnew->fname, conftree, p, - ptemp, 0); - } - } - } - - return; -} - -AP_DECLARE(void) ap_process_config_tree(server_rec *s, - ap_directive_t *conftree, - apr_pool_t *p, apr_pool_t *ptemp) -{ - const char *errmsg; - cmd_parms parms; - - parms = default_parms; - parms.pool = p; - parms.temp_pool = ptemp; - parms.server = s; - parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); - parms.limited = -1; - - errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults); - if (errmsg) { - ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, - "Syntax error on line %d of %s:", - parms.err_directive->line_num, - parms.err_directive->filename); - ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, - "%s", errmsg); - exit(1); - } -} - -AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, - request_rec *r, int override, - const char *d, const char *access_name) -{ - ap_configfile_t *f = NULL; - cmd_parms parms; - char *filename = NULL; - const struct htaccess_result *cache; - struct htaccess_result *new; - ap_conf_vector_t *dc = NULL; - apr_status_t status; - - /* firstly, search cache */ - for (cache = r->htaccess; cache != NULL; cache = cache->next) { - if (cache->override == override && strcmp(cache->dir, d) == 0) { - *result = cache->htaccess; - return OK; - } - } - - parms = default_parms; - parms.override = override; - parms.pool = r->pool; - parms.temp_pool = r->pool; - parms.server = r->server; - parms.path = apr_pstrdup(r->pool, d); - - /* loop through the access names and find the first one */ - while (access_name[0]) { - /* AFAICT; there is no use of the actual 'filename' against - * any canonicalization, so we will simply take the given - * name, ignoring case sensitivity and aliases - */ - filename = ap_make_full_path(r->pool, d, - ap_getword_conf(r->pool, &access_name)); - status = ap_pcfg_openfile(&f, r->pool, filename); - - if (status == APR_SUCCESS) { - const char *errmsg; - ap_directive_t *temptree = NULL; - - dc = ap_create_per_dir_config(r->pool); - - parms.config_file = f; - errmsg = ap_build_config(&parms, r->pool, r->pool, &temptree); - if (errmsg == NULL) - errmsg = ap_walk_config(temptree, &parms, dc); - - ap_cfg_closefile(f); - - if (errmsg) { - ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, - "%s: %s", filename, errmsg); - return HTTP_INTERNAL_SERVER_ERROR; - } - - *result = dc; - break; - } - else { - if (!APR_STATUS_IS_ENOENT(status) - && !APR_STATUS_IS_ENOTDIR(status)) { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, - "%s pcfg_openfile: unable to check htaccess file, " - "ensure it is readable", - filename); - apr_table_setn(r->notes, "error-notes", - "Server unable to read htaccess file, denying " - "access to be safe"); - return HTTP_FORBIDDEN; - } - } - } - - /* cache it */ - new = apr_palloc(r->pool, sizeof(struct htaccess_result)); - new->dir = parms.path; - new->override = override; - new->htaccess = dc; - - /* add to head of list */ - new->next = r->htaccess; - r->htaccess = new; - - return OK; -} - -AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p, - const char *hostname, - server_rec *main_server, - server_rec **ps) -{ - server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec)); - - /* TODO: this crap belongs in http_core */ - s->process = main_server->process; - s->server_admin = NULL; - s->server_hostname = NULL; - s->error_fname = NULL; - s->timeout = 0; - s->keep_alive_timeout = 0; - s->keep_alive = -1; - s->keep_alive_max = -1; - s->error_log = main_server->error_log; - s->loglevel = main_server->loglevel; - /* useful default, otherwise we get a port of 0 on redirects */ - s->port = main_server->port; - s->next = NULL; - - s->is_virtual = 1; - s->names = apr_array_make(p, 4, sizeof(char **)); - s->wild_names = apr_array_make(p, 4, sizeof(char **)); - - s->module_config = create_empty_config(p); - s->lookup_defaults = ap_create_per_dir_config(p); - - s->limit_req_line = main_server->limit_req_line; - s->limit_req_fieldsize = main_server->limit_req_fieldsize; - s->limit_req_fields = main_server->limit_req_fields; - - *ps = s; - - return ap_parse_vhost_addrs(p, hostname, s); -} - - -AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server) -{ - server_rec *virt; - - for (virt = main_server->next; virt; virt = virt->next) { - merge_server_configs(p, main_server->module_config, - virt->module_config); - - virt->lookup_defaults = - ap_merge_per_dir_configs(p, main_server->lookup_defaults, - virt->lookup_defaults); - - if (virt->server_admin == NULL) - virt->server_admin = main_server->server_admin; - - if (virt->timeout == 0) - virt->timeout = main_server->timeout; - - if (virt->keep_alive_timeout == 0) - virt->keep_alive_timeout = main_server->keep_alive_timeout; - - if (virt->keep_alive == -1) - virt->keep_alive = main_server->keep_alive; - - if (virt->keep_alive_max == -1) - virt->keep_alive_max = main_server->keep_alive_max; - - /* XXX: this is really something that should be dealt with by a - * post-config api phase - */ - ap_core_reorder_directories(p, virt); - } - - ap_core_reorder_directories(p, main_server); -} - -/***************************************************************** - * - * Getting *everything* configured... - */ - -static void init_config_globals(apr_pool_t *p) -{ - /* Global virtual host hash bucket pointers. Init to null. */ - ap_init_vhost_config(p); -} - -static server_rec *init_server_config(process_rec *process, apr_pool_t *p) -{ - apr_status_t rv; - server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec)); - - apr_file_open_stderr(&s->error_log, p); - s->process = process; - s->port = 0; - s->server_admin = DEFAULT_ADMIN; - s->server_hostname = NULL; - s->error_fname = DEFAULT_ERRORLOG; - s->loglevel = DEFAULT_LOGLEVEL; - s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE; - s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE; - s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS; - s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT); - s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT); - s->keep_alive_max = DEFAULT_KEEPALIVE; - s->keep_alive = 1; - s->next = NULL; - s->addrs = apr_pcalloc(p, sizeof(server_addr_rec)); - - /* NOT virtual host; don't match any real network interface */ - rv = apr_sockaddr_info_get(&s->addrs->host_addr, - NULL, APR_INET, 0, 0, p); - ap_assert(rv == APR_SUCCESS); /* otherwise: bug or no storage */ - - s->addrs->host_port = 0; /* matches any port */ - s->addrs->virthost = ""; /* must be non-NULL */ - s->names = s->wild_names = NULL; - - s->module_config = create_server_config(p, s); - s->lookup_defaults = create_default_per_dir_config(p); - - return s; -} - - -AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp, - const char *filename, - ap_directive_t **conftree) -{ - const char *confname; - apr_pool_t *p = process->pconf; - server_rec *s = init_server_config(process, p); - - init_config_globals(p); - - /* All server-wide config files now have the SAME syntax... */ - process_command_config(s, ap_server_pre_read_config, conftree, - p, ptemp); - - /* process_command_config may change the ServerRoot so - * compute this config file name afterwards. - */ - confname = ap_server_root_relative(p, filename); - - if (!confname) { - ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, - APR_EBADPATH, NULL, "Invalid config file path %s", - filename); - exit(1); - } - - ap_process_resource_config(s, confname, conftree, p, ptemp); - - process_command_config(s, ap_server_post_read_config, conftree, - p, ptemp); - - return s; -} - -AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s, - module *m) -{ - if (m->create_server_config) - ap_set_module_config(s->module_config, m, - (*m->create_server_config)(p, s)); - - if (m->create_dir_config) - ap_set_module_config(s->lookup_defaults, m, - (*m->create_dir_config)(p, NULL)); -} - -AP_DECLARE(void) ap_run_rewrite_args(process_rec *process) -{ - module *m; - - for (m = ap_top_module; m; m = m->next) { - if (m->rewrite_args) { - (*m->rewrite_args)(process); - } - } -} - -/******************************************************************** - * Configuration directives are restricted in terms of where they may - * appear in the main configuration files and/or .htaccess files according - * to the bitmask req_override in the command_rec structure. - * If any of the overrides set in req_override are also allowed in the - * context in which the command is read, then the command is allowed. - * The context is determined as follows: - * - * inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT); - * within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF; - * within .htaccess --> override = AllowOverride for current directory; - * - * the result is, well, a rather confusing set of possibilities for when - * a particular directive is allowed to be used. This procedure prints - * in English where the given (pc) directive can be used. - */ -static void show_overrides(const command_rec *pc, module *pm) -{ - int n = 0; - - printf("\tAllowed in *.conf "); - if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES)) - || ((pc->req_override & RSRC_CONF) - && ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT))))) { - printf("anywhere"); - } - else if (pc->req_override & RSRC_CONF) { - printf("only outside <Directory>, <Files> or <Location>"); - } - else { - printf("only inside <Directory>, <Files> or <Location>"); - } - - /* Warn if the directive is allowed inside <Directory> or .htaccess - * but module doesn't support per-dir configuration - */ - if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config) - printf(" [no per-dir config]"); - - if (pc->req_override & OR_ALL) { - printf(" and in .htaccess\n\twhen AllowOverride"); - - if ((pc->req_override & OR_ALL) == OR_ALL) { - printf(" isn't None"); - } - else { - printf(" includes "); - - if (pc->req_override & OR_AUTHCFG) { - if (n++) - printf(" or "); - - printf("AuthConfig"); - } - - if (pc->req_override & OR_LIMIT) { - if (n++) - printf(" or "); - - printf("Limit"); - } - - if (pc->req_override & OR_OPTIONS) { - if (n++) - printf(" or "); - - printf("Options"); - } - - if (pc->req_override & OR_FILEINFO) { - if (n++) - printf(" or "); - - printf("FileInfo"); - } - - if (pc->req_override & OR_INDEXES) { - if (n++) - printf(" or "); - - printf("Indexes"); - } - } - } - - printf("\n"); -} - -/* Show the preloaded configuration directives, the help string explaining - * the directive arguments, in what module they are handled, and in - * what parts of the configuration they are allowed. Used for httpd -L. - */ -AP_DECLARE(void) ap_show_directives(void) -{ - const command_rec *pc; - int n; - - for (n = 0; ap_loaded_modules[n]; ++n) { - for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) { - printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name); - - if (pc->errmsg) - printf("\t%s\n", pc->errmsg); - - show_overrides(pc, ap_loaded_modules[n]); - } - } -} - -/* Show the preloaded module names. Used for httpd -l. */ -AP_DECLARE(void) ap_show_modules(void) -{ - int n; - - printf("Compiled in modules:\n"); - for (n = 0; ap_loaded_modules[n]; ++n) - printf(" %s\n", ap_loaded_modules[n]->name); -} - -AP_DECLARE(const char *) ap_show_mpm(void) -{ - return MPM_NAME; -} diff --git a/rubbos/app/httpd-2.0.64/server/config.lo b/rubbos/app/httpd-2.0.64/server/config.lo deleted file mode 100644 index 75dddb8b..00000000 --- a/rubbos/app/httpd-2.0.64/server/config.lo +++ /dev/null @@ -1,12 +0,0 @@ -# config.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/config.o' - -# Name of the non-PIC object. -non_pic_object='config.o' - diff --git a/rubbos/app/httpd-2.0.64/server/config.m4 b/rubbos/app/httpd-2.0.64/server/config.m4 deleted file mode 100644 index 85fa4d17..00000000 --- a/rubbos/app/httpd-2.0.64/server/config.m4 +++ /dev/null @@ -1,15 +0,0 @@ -dnl ## Check for libraries - -dnl ## Check for header files - -AC_CHECK_HEADERS(bstring.h unistd.h) - -dnl ## Check for typedefs, structures, and compiler characteristics. - -dnl ## Check for library functions - -AC_CHECK_FUNCS(syslog) - -dnl Obsolete scoreboard code uses this. - AC_CHECK_HEADERS(sys/times.h) - AC_CHECK_FUNCS(times) diff --git a/rubbos/app/httpd-2.0.64/server/config.o b/rubbos/app/httpd-2.0.64/server/config.o Binary files differdeleted file mode 100644 index c5e795ab..00000000 --- a/rubbos/app/httpd-2.0.64/server/config.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/connection.c b/rubbos/app/httpd-2.0.64/server/connection.c deleted file mode 100644 index 52b8908f..00000000 --- a/rubbos/app/httpd-2.0.64/server/connection.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_strings.h" - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_connection.h" -#include "http_request.h" -#include "http_protocol.h" -#include "ap_mpm.h" -#include "mpm_default.h" -#include "http_config.h" -#include "http_core.h" -#include "http_vhost.h" -#include "scoreboard.h" -#include "http_log.h" -#include "util_filter.h" - -APR_HOOK_STRUCT( - APR_HOOK_LINK(create_connection) - APR_HOOK_LINK(process_connection) - APR_HOOK_LINK(pre_connection) -) -AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection, - (apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc), - (p, server, csd, conn_id, sbh, alloc), NULL) -AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED) -AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED) -/* - * More machine-dependent networking gooo... on some systems, - * you've got to be *really* sure that all the packets are acknowledged - * before closing the connection, since the client will not be able - * to see the last response if their TCP buffer is flushed by a RST - * packet from us, which is what the server's TCP stack will send - * if it receives any request data after closing the connection. - * - * In an ideal world, this function would be accomplished by simply - * setting the socket option SO_LINGER and handling it within the - * server's TCP stack while the process continues on to the next request. - * Unfortunately, it seems that most (if not all) operating systems - * block the server process on close() when SO_LINGER is used. - * For those that don't, see USE_SO_LINGER below. For the rest, - * we have created a home-brew lingering_close. - * - * Many operating systems tend to block, puke, or otherwise mishandle - * calls to shutdown only half of the connection. You should define - * NO_LINGCLOSE in ap_config.h if such is the case for your system. - */ -#ifndef MAX_SECS_TO_LINGER -#define MAX_SECS_TO_LINGER 30 -#endif - -AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c) -{ - apr_bucket_brigade *bb; - apr_bucket *b; - - bb = apr_brigade_create(c->pool, c->bucket_alloc); - - /* FLUSH bucket */ - b = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - - /* End Of Connection bucket */ - b = ap_bucket_eoc_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - - ap_pass_brigade(c->output_filters, bb); -} - -/* we now proceed to read from the client until we get EOF, or until - * MAX_SECS_TO_LINGER has passed. the reasons for doing this are - * documented in a draft: - * - * http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt - * - * in a nutshell -- if we don't make this effort we risk causing - * TCP RST packets to be sent which can tear down a connection before - * all the response data has been sent to the client. - */ -#define SECONDS_TO_LINGER 2 -AP_DECLARE(void) ap_lingering_close(conn_rec *c) -{ - char dummybuf[512]; - apr_size_t nbytes = sizeof(dummybuf); - apr_status_t rc; - apr_int32_t timeout; - apr_int32_t total_linger_time = 0; - apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module); - - if (!csd) { - return; - } - - ap_update_child_status(c->sbh, SERVER_CLOSING, NULL); - -#ifdef NO_LINGCLOSE - ap_flush_conn(c); /* just close it */ - apr_socket_close(csd); - return; -#endif - - /* Close the connection, being careful to send out whatever is still - * in our buffers. If possible, try to avoid a hard close until the - * client has ACKed our FIN and/or has stopped sending us data. - */ - - /* Send any leftover data to the client, but never try to again */ - ap_flush_conn(c); - - if (c->aborted) { - apr_socket_close(csd); - return; - } - - /* Shut down the socket for write, which will send a FIN - * to the peer. - */ - if (apr_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS - || c->aborted) { - apr_socket_close(csd); - return; - } - - /* Read all data from the peer until we reach "end-of-file" (FIN - * from peer) or we've exceeded our overall timeout. If the client does - * not send us bytes within 2 seconds (a value pulled from Apache 1.3 - * which seems to work well), close the connection. - */ - timeout = apr_time_from_sec(SECONDS_TO_LINGER); - apr_socket_timeout_set(csd, timeout); - apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1); - while (1) { - nbytes = sizeof(dummybuf); - rc = apr_recv(csd, dummybuf, &nbytes); - if (rc != APR_SUCCESS || nbytes == 0) - break; - - total_linger_time += SECONDS_TO_LINGER; - if (total_linger_time >= MAX_SECS_TO_LINGER) { - break; - } - } - - apr_socket_close(csd); - return; -} - -AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd) -{ - int rc; - ap_update_vhost_given_ip(c); - - rc = ap_run_pre_connection(c, csd); - if (rc != OK && rc != DONE) { - c->aborted = 1; - } - - if (!c->aborted) { - ap_run_process_connection(c); - } -} - diff --git a/rubbos/app/httpd-2.0.64/server/connection.lo b/rubbos/app/httpd-2.0.64/server/connection.lo deleted file mode 100644 index 78ca4b35..00000000 --- a/rubbos/app/httpd-2.0.64/server/connection.lo +++ /dev/null @@ -1,12 +0,0 @@ -# connection.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/connection.o' - -# Name of the non-PIC object. -non_pic_object='connection.o' - diff --git a/rubbos/app/httpd-2.0.64/server/connection.o b/rubbos/app/httpd-2.0.64/server/connection.o Binary files differdeleted file mode 100644 index 358e13a0..00000000 --- a/rubbos/app/httpd-2.0.64/server/connection.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/core.c b/rubbos/app/httpd-2.0.64/server/core.c deleted file mode 100644 index a6b1b4e6..00000000 --- a/rubbos/app/httpd-2.0.64/server/core.c +++ /dev/null @@ -1,4619 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_fnmatch.h" -#include "apr_hash.h" -#include "apr_thread_proc.h" /* for RLIMIT stuff */ -#include "apr_hooks.h" - -#define APR_WANT_IOVEC -#define APR_WANT_STRFUNC -#define APR_WANT_MEMFUNC -#include "apr_want.h" - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_protocol.h" /* For index_of_response(). Grump. */ -#include "http_request.h" -#include "http_vhost.h" -#include "http_main.h" /* For the default_handler below... */ -#include "http_log.h" -#include "rfc1413.h" -#include "util_md5.h" -#include "http_connection.h" -#include "apr_buckets.h" -#include "util_filter.h" -#include "util_ebcdic.h" -#include "mpm.h" -#include "mpm_common.h" -#include "scoreboard.h" -#include "mod_core.h" -#include "mod_proxy.h" -#include "ap_listen.h" - -/* LimitRequestBody handling */ -#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) -#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0) - -/* LimitXMLRequestBody handling */ -#define AP_LIMIT_UNSET ((long) -1) -#define AP_DEFAULT_LIMIT_XML_BODY ((size_t)1000000) - -#define AP_MIN_SENDFILE_BYTES (256) - -/* maximum include nesting level */ -#ifndef AP_MAX_INCLUDE_DEPTH -#define AP_MAX_INCLUDE_DEPTH (128) -#endif - -APR_HOOK_STRUCT( - APR_HOOK_LINK(get_mgmt_items) -) - -AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items, - (apr_pool_t *p, const char *val, apr_hash_t *ht), - (p, val, ht), OK, DECLINED) - -/* Server core module... This module provides support for really basic - * server operations, including options and commands which control the - * operation of other modules. Consider this the bureaucracy module. - * - * The core module also defines handlers, etc., do handle just enough - * to allow a server with the core module ONLY to actually serve documents - * (though it slaps DefaultType on all of 'em); this was useful in testing, - * but may not be worth preserving. - * - * This file could almost be mod_core.c, except for the stuff which affects - * the http_conf_globals. - */ - -/* Handles for core filters */ -AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle; -AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle; -AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle; -AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle; -AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle; - -/* magic pointer for ErrorDocument xxx "default" */ -static char errordocument_default; - -static void *create_core_dir_config(apr_pool_t *a, char *dir) -{ - core_dir_config *conf; - int i; - - conf = (core_dir_config *)apr_pcalloc(a, sizeof(core_dir_config)); - - /* conf->r and conf->d[_*] are initialized by dirsection() or left NULL */ - - conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL; - conf->opts_add = conf->opts_remove = OPT_NONE; - conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL; - - conf->content_md5 = 2; - conf->accept_path_info = 3; - - conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; - - conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET; - conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */ - conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS); - for (i = 0; i < METHODS; ++i) { - conf->satisfy[i] = SATISFY_NOSPEC; - } - -#ifdef RLIMIT_CPU - conf->limit_cpu = NULL; -#endif -#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) - conf->limit_mem = NULL; -#endif -#ifdef RLIMIT_NPROC - conf->limit_nproc = NULL; -#endif - - conf->limit_req_body = AP_LIMIT_REQ_BODY_UNSET; - conf->limit_xml_body = AP_LIMIT_UNSET; - conf->sec_file = apr_array_make(a, 2, sizeof(ap_conf_vector_t *)); - - conf->server_signature = srv_sig_unset; - - conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET; - conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; - - /* Overriding all negotiation - */ - conf->mime_type = NULL; - conf->handler = NULL; - conf->output_filters = NULL; - conf->input_filters = NULL; - - /* - * Flag for use of inodes in ETags. - */ - conf->etag_bits = ETAG_UNSET; - conf->etag_add = ETAG_UNSET; - conf->etag_remove = ETAG_UNSET; - - conf->enable_mmap = ENABLE_MMAP_UNSET; - conf->enable_sendfile = ENABLE_SENDFILE_UNSET; - conf->allow_encoded_slashes = 0; - - return (void *)conf; -} - -/* - * Overlay one hash table of ct_output_filters onto another - */ -static void *merge_ct_filters(apr_pool_t *p, - const void *key, - apr_ssize_t klen, - const void *overlay_val, - const void *base_val, - const void *data) -{ - ap_filter_rec_t *cur; - const ap_filter_rec_t *overlay_info = (const ap_filter_rec_t *)overlay_val; - const ap_filter_rec_t *base_info = (const ap_filter_rec_t *)base_val; - - cur = NULL; - - while (overlay_info) { - ap_filter_rec_t *new; - - new = apr_pcalloc(p, sizeof(ap_filter_rec_t)); - new->name = apr_pstrdup(p, overlay_info->name); - new->next = cur; - cur = new; - overlay_info = overlay_info->next; - } - - while (base_info) { - ap_filter_rec_t *f; - int found = 0; - - /* We can't have dups. */ - f = cur; - while (f) { - if (!strcasecmp(base_info->name, f->name)) { - found = 1; - break; - } - - f = f->next; - } - - if (!found) { - f = apr_pcalloc(p, sizeof(ap_filter_rec_t)); - f->name = apr_pstrdup(p, base_info->name); - f->next = cur; - cur = f; - } - - base_info = base_info->next; - } - - return cur; -} - -static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) -{ - core_dir_config *base = (core_dir_config *)basev; - core_dir_config *new = (core_dir_config *)newv; - core_dir_config *conf; - int i; - - /* Create this conf by duplicating the base, replacing elements - * (or creating copies for merging) where new-> values exist. - */ - conf = (core_dir_config *)apr_palloc(a, sizeof(core_dir_config)); - memcpy(conf, base, sizeof(core_dir_config)); - - conf->d = new->d; - conf->d_is_fnmatch = new->d_is_fnmatch; - conf->d_components = new->d_components; - conf->r = new->r; - - if (new->opts & OPT_UNSET) { - /* there was no explicit setting of new->opts, so we merge - * preserve the invariant (opts_add & opts_remove) == 0 - */ - conf->opts_add = (conf->opts_add & ~new->opts_remove) | new->opts_add; - conf->opts_remove = (conf->opts_remove & ~new->opts_add) - | new->opts_remove; - conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add; - if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) { - conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES; - } - } - else { - /* otherwise we just copy, because an explicit opts setting - * overrides all earlier +/- modifiers - */ - conf->opts = new->opts; - conf->opts_add = new->opts_add; - conf->opts_remove = new->opts_remove; - } - - if (!(new->override & OR_UNSET)) { - conf->override = new->override; - } - - if (new->ap_default_type) { - conf->ap_default_type = new->ap_default_type; - } - - if (new->ap_auth_type) { - conf->ap_auth_type = new->ap_auth_type; - } - - if (new->ap_auth_name) { - conf->ap_auth_name = new->ap_auth_name; - } - - if (new->ap_requires) { - conf->ap_requires = new->ap_requires; - } - - if (conf->response_code_strings == NULL) { - conf->response_code_strings = new->response_code_strings; - } - else if (new->response_code_strings != NULL) { - /* If we merge, the merge-result must have it's own array - */ - conf->response_code_strings = apr_palloc(a, - sizeof(*conf->response_code_strings) * RESPONSE_CODES); - memcpy(conf->response_code_strings, base->response_code_strings, - sizeof(*conf->response_code_strings) * RESPONSE_CODES); - - for (i = 0; i < RESPONSE_CODES; ++i) { - if (new->response_code_strings[i] != NULL) { - conf->response_code_strings[i] = new->response_code_strings[i]; - } - } - } - /* Otherwise we simply use the base->response_code_strings array - */ - - if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET) { - conf->hostname_lookups = new->hostname_lookups; - } - - if ((new->do_rfc1413 & 2) == 0) { - conf->do_rfc1413 = new->do_rfc1413; - } - - if ((new->content_md5 & 2) == 0) { - conf->content_md5 = new->content_md5; - } - - if (new->accept_path_info != 3) { - conf->accept_path_info = new->accept_path_info; - } - - if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) { - conf->use_canonical_name = new->use_canonical_name; - } - -#ifdef RLIMIT_CPU - if (new->limit_cpu) { - conf->limit_cpu = new->limit_cpu; - } -#endif - -#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) - if (new->limit_mem) { - conf->limit_mem = new->limit_mem; - } -#endif - -#ifdef RLIMIT_NPROC - if (new->limit_nproc) { - conf->limit_nproc = new->limit_nproc; - } -#endif - - if (new->limit_req_body != AP_LIMIT_REQ_BODY_UNSET) { - conf->limit_req_body = new->limit_req_body; - } - - if (new->limit_xml_body != AP_LIMIT_UNSET) - conf->limit_xml_body = new->limit_xml_body; - else - conf->limit_xml_body = base->limit_xml_body; - - if (!conf->sec_file) { - conf->sec_file = new->sec_file; - } - else if (new->sec_file) { - /* If we merge, the merge-result must have it's own array - */ - conf->sec_file = apr_array_append(a, base->sec_file, new->sec_file); - } - /* Otherwise we simply use the base->sec_file array - */ - - /* use a separate ->satisfy[] array either way */ - conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS); - for (i = 0; i < METHODS; ++i) { - if (new->satisfy[i] != SATISFY_NOSPEC) { - conf->satisfy[i] = new->satisfy[i]; - } else { - conf->satisfy[i] = base->satisfy[i]; - } - } - - if (new->server_signature != srv_sig_unset) { - conf->server_signature = new->server_signature; - } - - if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) { - conf->add_default_charset = new->add_default_charset; - conf->add_default_charset_name = new->add_default_charset_name; - } - - /* Overriding all negotiation - */ - if (new->mime_type) { - conf->mime_type = new->mime_type; - } - - if (new->handler) { - conf->handler = new->handler; - } - - if (new->output_filters) { - conf->output_filters = new->output_filters; - } - - if (new->input_filters) { - conf->input_filters = new->input_filters; - } - - if (conf->ct_output_filters && new->ct_output_filters) { - conf->ct_output_filters = apr_hash_merge(a, - new->ct_output_filters, - conf->ct_output_filters, - merge_ct_filters, - NULL); - } - else if (new->ct_output_filters) { - conf->ct_output_filters = apr_hash_copy(a, new->ct_output_filters); - } - else if (conf->ct_output_filters) { - /* That memcpy above isn't enough. */ - conf->ct_output_filters = apr_hash_copy(a, base->ct_output_filters); - } - - /* - * Now merge the setting of the FileETag directive. - */ - if (new->etag_bits == ETAG_UNSET) { - conf->etag_add = - (conf->etag_add & (~ new->etag_remove)) | new->etag_add; - conf->etag_remove = - (conf->opts_remove & (~ new->etag_add)) | new->etag_remove; - conf->etag_bits = - (conf->etag_bits & (~ conf->etag_remove)) | conf->etag_add; - } - else { - conf->etag_bits = new->etag_bits; - conf->etag_add = new->etag_add; - conf->etag_remove = new->etag_remove; - } - - if (conf->etag_bits != ETAG_NONE) { - conf->etag_bits &= (~ ETAG_NONE); - } - - if (new->enable_mmap != ENABLE_MMAP_UNSET) { - conf->enable_mmap = new->enable_mmap; - } - - if (new->enable_sendfile != ENABLE_SENDFILE_UNSET) { - conf->enable_sendfile = new->enable_sendfile; - } - - conf->allow_encoded_slashes = new->allow_encoded_slashes; - - return (void*)conf; -} - -static void *create_core_server_config(apr_pool_t *a, server_rec *s) -{ - core_server_config *conf; - int is_virtual = s->is_virtual; - - conf = (core_server_config *)apr_pcalloc(a, sizeof(core_server_config)); - -#ifdef GPROF - conf->gprof_dir = NULL; -#endif - - conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME; - conf->ap_document_root = is_virtual ? NULL : DOCUMENT_LOCATION; - conf->sec_dir = apr_array_make(a, 40, sizeof(ap_conf_vector_t *)); - conf->sec_url = apr_array_make(a, 40, sizeof(ap_conf_vector_t *)); - - /* recursion stopper */ - conf->redirect_limit = 0; /* 0 == unset */ - conf->subreq_limit = 0; - - conf->trace_enable = AP_TRACE_UNSET; - - return (void *)conf; -} - -static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) -{ - core_server_config *base = (core_server_config *)basev; - core_server_config *virt = (core_server_config *)virtv; - core_server_config *conf; - - conf = (core_server_config *)apr_palloc(p, sizeof(core_server_config)); - memcpy(conf, virt, sizeof(core_server_config)); - - if (!conf->access_name) { - conf->access_name = base->access_name; - } - - if (!conf->ap_document_root) { - conf->ap_document_root = base->ap_document_root; - } - - conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir); - conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url); - - conf->redirect_limit = virt->redirect_limit - ? virt->redirect_limit - : base->redirect_limit; - - conf->subreq_limit = virt->subreq_limit - ? virt->subreq_limit - : base->subreq_limit; - - conf->trace_enable = (virt->trace_enable != AP_TRACE_UNSET) - ? virt->trace_enable - : base->trace_enable; - - return conf; -} - -/* Add per-directory configuration entry (for <directory> section); - * these are part of the core server config. - */ - -AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config) -{ - core_server_config *sconf = ap_get_module_config(s->module_config, - &core_module); - void **new_space = (void **)apr_array_push(sconf->sec_dir); - - *new_space = dir_config; -} - -AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config) -{ - core_server_config *sconf = ap_get_module_config(s->module_config, - &core_module); - void **new_space = (void **)apr_array_push(sconf->sec_url); - - *new_space = url_config; -} - -AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config) -{ - void **new_space = (void **)apr_array_push(conf->sec_file); - - *new_space = url_config; -} - -/* We need to do a stable sort, qsort isn't stable. So to make it stable - * we'll be maintaining the original index into the list, and using it - * as the minor key during sorting. The major key is the number of - * components (where the root component is zero). - */ -struct reorder_sort_rec { - ap_conf_vector_t *elt; - int orig_index; -}; - -static int reorder_sorter(const void *va, const void *vb) -{ - const struct reorder_sort_rec *a = va; - const struct reorder_sort_rec *b = vb; - core_dir_config *core_a; - core_dir_config *core_b; - - core_a = ap_get_module_config(a->elt, &core_module); - core_b = ap_get_module_config(b->elt, &core_module); - - /* a regex always sorts after a non-regex - */ - if (!core_a->r && core_b->r) { - return -1; - } - else if (core_a->r && !core_b->r) { - return 1; - } - - /* we always sort next by the number of components - */ - if (core_a->d_components < core_b->d_components) { - return -1; - } - else if (core_a->d_components > core_b->d_components) { - return 1; - } - - /* They have the same number of components, we now have to compare - * the minor key to maintain the original order (from the config.) - */ - return a->orig_index - b->orig_index; -} - -void ap_core_reorder_directories(apr_pool_t *p, server_rec *s) -{ - core_server_config *sconf; - apr_array_header_t *sec_dir; - struct reorder_sort_rec *sortbin; - int nelts; - ap_conf_vector_t **elts; - int i; - apr_pool_t *tmp; - - sconf = ap_get_module_config(s->module_config, &core_module); - sec_dir = sconf->sec_dir; - nelts = sec_dir->nelts; - elts = (ap_conf_vector_t **)sec_dir->elts; - - if (!nelts) { - /* simple case of already being sorted... */ - /* We're not checking this condition to be fast... we're checking - * it to avoid trying to palloc zero bytes, which can trigger some - * memory debuggers to barf - */ - return; - } - - /* we have to allocate tmp space to do a stable sort */ - apr_pool_create(&tmp, p); - sortbin = apr_palloc(tmp, sec_dir->nelts * sizeof(*sortbin)); - for (i = 0; i < nelts; ++i) { - sortbin[i].orig_index = i; - sortbin[i].elt = elts[i]; - } - - qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter); - - /* and now copy back to the original array */ - for (i = 0; i < nelts; ++i) { - elts[i] = sortbin[i].elt; - } - - apr_pool_destroy(tmp); -} - -/***************************************************************** - * - * There are some elements of the core config structures in which - * other modules have a legitimate interest (this is ugly, but necessary - * to preserve NCSA back-compatibility). So, we have a bunch of accessors - * here... - */ - -AP_DECLARE(int) ap_allow_options(request_rec *r) -{ - core_dir_config *conf = - (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - - return conf->opts; -} - -AP_DECLARE(int) ap_allow_overrides(request_rec *r) -{ - core_dir_config *conf; - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - return conf->override; -} - -AP_DECLARE(const char *) ap_auth_type(request_rec *r) -{ - core_dir_config *conf; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - return conf->ap_auth_type; -} - -AP_DECLARE(const char *) ap_auth_name(request_rec *r) -{ - core_dir_config *conf; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - return conf->ap_auth_name; -} - -AP_DECLARE(const char *) ap_default_type(request_rec *r) -{ - core_dir_config *conf; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - return conf->ap_default_type - ? conf->ap_default_type - : DEFAULT_CONTENT_TYPE; -} - -AP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */ -{ - core_server_config *conf; - - conf = (core_server_config *)ap_get_module_config(r->server->module_config, - &core_module); - - return conf->ap_document_root; -} - -AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r) -{ - core_dir_config *conf; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - return conf->ap_requires; -} - -AP_DECLARE(int) ap_satisfies(request_rec *r) -{ - core_dir_config *conf; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - return conf->satisfy[r->method_number]; -} - -/* Should probably just get rid of this... the only code that cares is - * part of the core anyway (and in fact, it isn't publicised to other - * modules). - */ - -char *ap_response_code_string(request_rec *r, int error_index) -{ - core_dir_config *dirconf; - core_request_config *reqconf; - - /* check for string registered via ap_custom_response() first */ - reqconf = (core_request_config *)ap_get_module_config(r->request_config, - &core_module); - if (reqconf->response_code_strings != NULL && - reqconf->response_code_strings[error_index] != NULL) { - return reqconf->response_code_strings[error_index]; - } - - /* check for string specified via ErrorDocument */ - dirconf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - if (dirconf->response_code_strings == NULL) { - return NULL; - } - - if (dirconf->response_code_strings[error_index] == &errordocument_default) { - return NULL; - } - - return dirconf->response_code_strings[error_index]; -} - - -/* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */ -static APR_INLINE void do_double_reverse (conn_rec *conn) -{ - apr_sockaddr_t *sa; - apr_status_t rv; - - if (conn->double_reverse) { - /* already done */ - return; - } - - if (conn->remote_host == NULL || conn->remote_host[0] == '\0') { - /* single reverse failed, so don't bother */ - conn->double_reverse = -1; - return; - } - - rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool); - if (rv == APR_SUCCESS) { - while (sa) { - if (apr_sockaddr_equal(sa, conn->remote_addr)) { - conn->double_reverse = 1; - return; - } - - sa = sa->next; - } - } - - conn->double_reverse = -1; -} - -AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, - int type, int *str_is_ip) -{ - int hostname_lookups; - - if (str_is_ip) { /* if caller wants to know */ - *str_is_ip = 0; - } - - /* If we haven't checked the host name, and we want to */ - if (dir_config) { - hostname_lookups = - ((core_dir_config *)ap_get_module_config(dir_config, &core_module)) - ->hostname_lookups; - - if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) { - hostname_lookups = HOSTNAME_LOOKUP_OFF; - } - } - else { - /* the default */ - hostname_lookups = HOSTNAME_LOOKUP_OFF; - } - - if (type != REMOTE_NOLOOKUP - && conn->remote_host == NULL - && (type == REMOTE_DOUBLE_REV - || hostname_lookups != HOSTNAME_LOOKUP_OFF)) { - - if (apr_getnameinfo(&conn->remote_host, conn->remote_addr, 0) - == APR_SUCCESS) { - ap_str_tolower(conn->remote_host); - - if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) { - do_double_reverse(conn); - if (conn->double_reverse != 1) { - conn->remote_host = NULL; - } - } - } - - /* if failed, set it to the NULL string to indicate error */ - if (conn->remote_host == NULL) { - conn->remote_host = ""; - } - } - - if (type == REMOTE_DOUBLE_REV) { - do_double_reverse(conn); - if (conn->double_reverse == -1) { - return NULL; - } - } - - /* - * Return the desired information; either the remote DNS name, if found, - * or either NULL (if the hostname was requested) or the IP address - * (if any identifier was requested). - */ - if (conn->remote_host != NULL && conn->remote_host[0] != '\0') { - return conn->remote_host; - } - else { - if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) { - return NULL; - } - else { - if (str_is_ip) { /* if caller wants to know */ - *str_is_ip = 1; - } - - return conn->remote_ip; - } - } -} - -AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r) -{ - core_dir_config *dir_conf; - - if (r->connection->remote_logname != NULL) { - return r->connection->remote_logname; - } - - /* If we haven't checked the identity, and we want to */ - dir_conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - if (dir_conf->do_rfc1413 & 1) { - return ap_rfc1413(r->connection, r->server); - } - else { - return NULL; - } -} - -/* There are two options regarding what the "name" of a server is. The - * "canonical" name as defined by ServerName and Port, or the "client's - * name" as supplied by a possible Host: header or full URI. We never - * trust the port passed in the client's headers, we always use the - * port of the actual socket. - * - * The DNS option to UseCanonicalName causes this routine to do a - * reverse lookup on the local IP address of the connection and use - * that for the ServerName. This makes its value more reliable while - * at the same time allowing Demon's magic virtual hosting to work. - * The assumption is that DNS lookups are sufficiently quick... - * -- fanf 1998-10-03 - */ -AP_DECLARE(const char *) ap_get_server_name(request_rec *r) -{ - conn_rec *conn = r->connection; - core_dir_config *d; - - d = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) { - return r->hostname ? r->hostname : r->server->server_hostname; - } - - if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) { - if (conn->local_host == NULL) { - if (apr_getnameinfo(&conn->local_host, - conn->local_addr, 0) != APR_SUCCESS) - conn->local_host = apr_pstrdup(conn->pool, - r->server->server_hostname); - else { - ap_str_tolower(conn->local_host); - } - } - - return conn->local_host; - } - - /* default */ - return r->server->server_hostname; -} - -/* - * Get the current server name from the request for the purposes - * of using in a URL. If the server name is an IPv6 literal - * address, it will be returned in URL format (e.g., "[fe80::1]"). - */ -static const char *get_server_name_for_url(request_rec *r) -{ - const char *plain_server_name = ap_get_server_name(r); - -#if APR_HAVE_IPV6 - if (ap_strchr_c(plain_server_name, ':')) { /* IPv6 literal? */ - return apr_psprintf(r->pool, "[%s]", plain_server_name); - } -#endif - return plain_server_name; -} - -AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r) -{ - apr_port_t port; - core_dir_config *d = - (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - - if (d->use_canonical_name == USE_CANONICAL_NAME_OFF - || d->use_canonical_name == USE_CANONICAL_NAME_DNS) { - - /* With UseCanonicalName off Apache will form self-referential - * URLs using the hostname and port supplied by the client if - * any are supplied (otherwise it will use the canonical name). - */ - port = r->parsed_uri.port_str ? r->parsed_uri.port : - r->server->port ? r->server->port : - ap_default_port(r); - } - else { /* d->use_canonical_name == USE_CANONICAL_NAME_ON */ - - /* With UseCanonicalName on (and in all versions prior to 1.3) - * Apache will use the hostname and port specified in the - * ServerName directive to construct a canonical name for the - * server. (If no port was specified in the ServerName - * directive, Apache uses the port supplied by the client if - * any is supplied, and finally the default port for the protocol - * used. - */ - port = r->server->port ? r->server->port : - r->connection->local_addr->port ? r->connection->local_addr->port : - ap_default_port(r); - } - - /* default */ - return port; -} - -AP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri, - request_rec *r) -{ - unsigned port = ap_get_server_port(r); - const char *host = get_server_name_for_url(r); - - if (ap_is_default_port(port, r)) { - return apr_pstrcat(p, ap_http_method(r), "://", host, uri, NULL); - } - - return apr_psprintf(p, "%s://%s:%u%s", ap_http_method(r), host, port, uri); -} - -AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r) -{ - core_dir_config *d = - (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - - if (d->limit_req_body == AP_LIMIT_REQ_BODY_UNSET) { - return AP_DEFAULT_LIMIT_REQ_BODY; - } - - return d->limit_req_body; -} - - -/***************************************************************** - * - * Commands... this module handles almost all of the NCSA httpd.conf - * commands, but most of the old srm.conf is in the the modules. - */ - - -/* returns a parent if it matches the given directive */ -static const ap_directive_t * find_parent(const ap_directive_t *dirp, - const char *what) -{ - while (dirp->parent != NULL) { - dirp = dirp->parent; - - /* ### it would be nice to have atom-ized directives */ - if (strcasecmp(dirp->directive, what) == 0) - return dirp; - } - - return NULL; -} - -AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd, - unsigned forbidden) -{ - const char *gt = (cmd->cmd->name[0] == '<' - && cmd->cmd->name[strlen(cmd->cmd->name)-1] != '>') - ? ">" : ""; - const ap_directive_t *found; - - if ((forbidden & NOT_IN_VIRTUALHOST) && cmd->server->is_virtual) { - return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, - " cannot occur within <VirtualHost> section", NULL); - } - - if ((forbidden & NOT_IN_LIMIT) && cmd->limited != -1) { - return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, - " cannot occur within <Limit> section", NULL); - } - - if ((forbidden & NOT_IN_DIR_LOC_FILE) == NOT_IN_DIR_LOC_FILE) { - if (cmd->path != NULL) { - return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, - " cannot occur within <Directory/Location/Files> " - "section", NULL); - } - if (cmd->cmd->req_override & EXEC_ON_READ) { - /* EXEC_ON_READ must be NOT_IN_DIR_LOC_FILE, if not, it will - * (deliberately) segfault below in the individual tests... - */ - return NULL; - } - } - - if (((forbidden & NOT_IN_DIRECTORY) - && ((found = find_parent(cmd->directive, "<Directory")) - || (found = find_parent(cmd->directive, "<DirectoryMatch")))) - || ((forbidden & NOT_IN_LOCATION) - && ((found = find_parent(cmd->directive, "<Location")) - || (found = find_parent(cmd->directive, "<LocationMatch")))) - || ((forbidden & NOT_IN_FILES) - && ((found = find_parent(cmd->directive, "<Files")) - || (found = find_parent(cmd->directive, "<FilesMatch"))))) { - return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, - " cannot occur within ", found->directive, - "> section", NULL); - } - - return NULL; -} - -static const char *set_access_name(cmd_parms *cmd, void *dummy, - const char *arg) -{ - void *sconf = cmd->server->module_config; - core_server_config *conf = ap_get_module_config(sconf, &core_module); - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - conf->access_name = apr_pstrdup(cmd->pool, arg); - return NULL; -} - -#ifdef GPROF -static const char *set_gprof_dir(cmd_parms *cmd, void *dummy, const char *arg) -{ - void *sconf = cmd->server->module_config; - core_server_config *conf = ap_get_module_config(sconf, &core_module); - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - conf->gprof_dir = apr_pstrdup(cmd->pool, arg); - return NULL; -} -#endif /*GPROF*/ - -static const char *set_add_default_charset(cmd_parms *cmd, - void *d_, const char *arg) -{ - core_dir_config *d = d_; - - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - if (!strcasecmp(arg, "Off")) { - d->add_default_charset = ADD_DEFAULT_CHARSET_OFF; - } - else if (!strcasecmp(arg, "On")) { - d->add_default_charset = ADD_DEFAULT_CHARSET_ON; - d->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; - } - else { - d->add_default_charset = ADD_DEFAULT_CHARSET_ON; - d->add_default_charset_name = arg; - } - - return NULL; -} - -static const char *set_document_root(cmd_parms *cmd, void *dummy, - const char *arg) -{ - void *sconf = cmd->server->module_config; - core_server_config *conf = ap_get_module_config(sconf, &core_module); - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - /* TODO: ap_configtestonly && ap_docrootcheck && */ - /* XXX Shouldn't this be relative to ServerRoot ??? */ - if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg, - APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS - || !ap_is_directory(cmd->pool, arg)) { - if (cmd->server->is_virtual) { - ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, - cmd->pool, - "Warning: DocumentRoot [%s] does not exist", - arg); - conf->ap_document_root = arg; - } - else { - return "DocumentRoot must be a directory"; - } - } - return NULL; -} - -AP_DECLARE(void) ap_custom_response(request_rec *r, int status, - const char *string) -{ - core_request_config *conf = - ap_get_module_config(r->request_config, &core_module); - int idx; - - if (conf->response_code_strings == NULL) { - conf->response_code_strings = - apr_pcalloc(r->pool, - sizeof(*conf->response_code_strings) * RESPONSE_CODES); - } - - idx = ap_index_of_response(status); - - conf->response_code_strings[idx] = - ((ap_is_url(string) || (*string == '/')) && (*string != '"')) ? - apr_pstrdup(r->pool, string) : apr_pstrcat(r->pool, "\"", string, NULL); -} - -static const char *set_error_document(cmd_parms *cmd, void *conf_, - const char *errno_str, const char *msg) -{ - core_dir_config *conf = conf_; - int error_number, index_number, idx500; - enum { MSG, LOCAL_PATH, REMOTE_PATH } what = MSG; - - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - /* 1st parameter should be a 3 digit number, which we recognize; - * convert it into an array index - */ - error_number = atoi(errno_str); - idx500 = ap_index_of_response(HTTP_INTERNAL_SERVER_ERROR); - - if (error_number == HTTP_INTERNAL_SERVER_ERROR) { - index_number = idx500; - } - else if ((index_number = ap_index_of_response(error_number)) == idx500) { - return apr_pstrcat(cmd->pool, "Unsupported HTTP response code ", - errno_str, NULL); - } - - /* Heuristic to determine second argument. */ - if (ap_strchr_c(msg,' ')) - what = MSG; - else if (msg[0] == '/') - what = LOCAL_PATH; - else if (ap_is_url(msg)) - what = REMOTE_PATH; - else - what = MSG; - - /* The entry should be ignored if it is a full URL for a 401 error */ - - if (error_number == 401 && what == REMOTE_PATH) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, - "cannot use a full URL in a 401 ErrorDocument " - "directive --- ignoring!"); - } - else { /* Store it... */ - if (conf->response_code_strings == NULL) { - conf->response_code_strings = - apr_pcalloc(cmd->pool, - sizeof(*conf->response_code_strings) * - RESPONSE_CODES); - } - - if (strcmp(msg, "default") == 0) { - /* special case: ErrorDocument 404 default restores the - * canned server error response - */ - conf->response_code_strings[index_number] = &errordocument_default; - } - else { - /* hack. Prefix a " if it is a msg; as that is what - * http_protocol.c relies on to distinguish between - * a msg and a (local) path. - */ - conf->response_code_strings[index_number] = (what == MSG) ? - apr_pstrcat(cmd->pool, "\"",msg,NULL) : - apr_pstrdup(cmd->pool, msg); - } - } - - return NULL; -} - -static const char *set_override(cmd_parms *cmd, void *d_, const char *l) -{ - core_dir_config *d = d_; - char *w; - - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - d->override = OR_NONE; - while (l[0]) { - w = ap_getword_conf(cmd->pool, &l); - if (!strcasecmp(w, "Limit")) { - d->override |= OR_LIMIT; - } - else if (!strcasecmp(w, "Options")) { - d->override |= OR_OPTIONS; - } - else if (!strcasecmp(w, "FileInfo")) { - d->override |= OR_FILEINFO; - } - else if (!strcasecmp(w, "AuthConfig")) { - d->override |= OR_AUTHCFG; - } - else if (!strcasecmp(w, "Indexes")) { - d->override |= OR_INDEXES; - } - else if (!strcasecmp(w, "None")) { - d->override = OR_NONE; - } - else if (!strcasecmp(w, "All")) { - d->override = OR_ALL; - } - else { - return apr_pstrcat(cmd->pool, "Illegal override option ", w, NULL); - } - - d->override &= ~OR_UNSET; - } - - return NULL; -} - -static const char *set_options(cmd_parms *cmd, void *d_, const char *l) -{ - core_dir_config *d = d_; - allow_options_t opt; - int first = 1; - char action; - - while (l[0]) { - char *w = ap_getword_conf(cmd->pool, &l); - action = '\0'; - - if (*w == '+' || *w == '-') { - action = *(w++); - } - else if (first) { - d->opts = OPT_NONE; - first = 0; - } - - if (!strcasecmp(w, "Indexes")) { - opt = OPT_INDEXES; - } - else if (!strcasecmp(w, "Includes")) { - opt = OPT_INCLUDES; - } - else if (!strcasecmp(w, "IncludesNOEXEC")) { - opt = (OPT_INCLUDES | OPT_INCNOEXEC); - } - else if (!strcasecmp(w, "FollowSymLinks")) { - opt = OPT_SYM_LINKS; - } - else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) { - opt = OPT_SYM_OWNER; - } - else if (!strcasecmp(w, "execCGI")) { - opt = OPT_EXECCGI; - } - else if (!strcasecmp(w, "MultiViews")) { - opt = OPT_MULTI; - } - else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ - opt = OPT_MULTI|OPT_EXECCGI; - } - else if (!strcasecmp(w, "None")) { - opt = OPT_NONE; - } - else if (!strcasecmp(w, "All")) { - opt = OPT_ALL; - } - else { - return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL); - } - - /* we ensure the invariant (d->opts_add & d->opts_remove) == 0 */ - if (action == '-') { - d->opts_remove |= opt; - d->opts_add &= ~opt; - d->opts &= ~opt; - } - else if (action == '+') { - d->opts_add |= opt; - d->opts_remove &= ~opt; - d->opts |= opt; - } - else { - d->opts |= opt; - } - } - - return NULL; -} - -/* - * Note what data should be used when forming file ETag values. - * It would be nicer to do this as an ITERATE, but then we couldn't - * remember the +/- state properly. - */ -static const char *set_etag_bits(cmd_parms *cmd, void *mconfig, - const char *args_p) -{ - core_dir_config *cfg; - etag_components_t bit; - char action; - char *token; - const char *args; - int valid; - int first; - int explicit; - - cfg = (core_dir_config *)mconfig; - - args = args_p; - first = 1; - explicit = 0; - while (args[0] != '\0') { - action = '*'; - bit = ETAG_UNSET; - valid = 1; - token = ap_getword_conf(cmd->pool, &args); - if ((*token == '+') || (*token == '-')) { - action = *token; - token++; - } - else { - /* - * The occurrence of an absolute setting wipes - * out any previous relative ones. The first such - * occurrence forgets any inherited ones, too. - */ - if (first) { - cfg->etag_bits = ETAG_UNSET; - cfg->etag_add = ETAG_UNSET; - cfg->etag_remove = ETAG_UNSET; - first = 0; - } - } - - if (strcasecmp(token, "None") == 0) { - if (action != '*') { - valid = 0; - } - else { - cfg->etag_bits = bit = ETAG_NONE; - explicit = 1; - } - } - else if (strcasecmp(token, "All") == 0) { - if (action != '*') { - valid = 0; - } - else { - explicit = 1; - cfg->etag_bits = bit = ETAG_ALL; - } - } - else if (strcasecmp(token, "Size") == 0) { - bit = ETAG_SIZE; - } - else if ((strcasecmp(token, "LMTime") == 0) - || (strcasecmp(token, "MTime") == 0) - || (strcasecmp(token, "LastModified") == 0)) { - bit = ETAG_MTIME; - } - else if (strcasecmp(token, "INode") == 0) { - bit = ETAG_INODE; - } - else { - return apr_pstrcat(cmd->pool, "Unknown keyword '", - token, "' for ", cmd->cmd->name, - " directive", NULL); - } - - if (! valid) { - return apr_pstrcat(cmd->pool, cmd->cmd->name, " keyword '", - token, "' cannot be used with '+' or '-'", - NULL); - } - - if (action == '+') { - /* - * Make sure it's in the 'add' list and absent from the - * 'subtract' list. - */ - cfg->etag_add |= bit; - cfg->etag_remove &= (~ bit); - } - else if (action == '-') { - cfg->etag_remove |= bit; - cfg->etag_add &= (~ bit); - } - else { - /* - * Non-relative values wipe out any + or - values - * accumulated so far. - */ - cfg->etag_bits |= bit; - cfg->etag_add = ETAG_UNSET; - cfg->etag_remove = ETAG_UNSET; - explicit = 1; - } - } - - /* - * Any setting at all will clear the 'None' and 'Unset' bits. - */ - - if (cfg->etag_add != ETAG_UNSET) { - cfg->etag_add &= (~ ETAG_UNSET); - } - - if (cfg->etag_remove != ETAG_UNSET) { - cfg->etag_remove &= (~ ETAG_UNSET); - } - - if (explicit) { - cfg->etag_bits &= (~ ETAG_UNSET); - - if ((cfg->etag_bits & ETAG_NONE) != ETAG_NONE) { - cfg->etag_bits &= (~ ETAG_NONE); - } - } - - return NULL; -} - -static const char *set_enable_mmap(cmd_parms *cmd, void *d_, - const char *arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - if (strcasecmp(arg, "on") == 0) { - d->enable_mmap = ENABLE_MMAP_ON; - } - else if (strcasecmp(arg, "off") == 0) { - d->enable_mmap = ENABLE_MMAP_OFF; - } - else { - return "parameter must be 'on' or 'off'"; - } - - return NULL; -} - -static const char *set_enable_sendfile(cmd_parms *cmd, void *d_, - const char *arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - if (strcasecmp(arg, "on") == 0) { - d->enable_sendfile = ENABLE_SENDFILE_ON; - } - else if (strcasecmp(arg, "off") == 0) { - d->enable_sendfile = ENABLE_SENDFILE_OFF; - } - else { - return "parameter must be 'on' or 'off'"; - } - - return NULL; -} - -static const char *satisfy(cmd_parms *cmd, void *c_, const char *arg) -{ - core_dir_config *c = c_; - int satisfy = SATISFY_NOSPEC; - int i; - - if (!strcasecmp(arg, "all")) { - satisfy = SATISFY_ALL; - } - else if (!strcasecmp(arg, "any")) { - satisfy = SATISFY_ANY; - } - else { - return "Satisfy either 'any' or 'all'."; - } - - for (i = 0; i < METHODS; ++i) { - if (cmd->limited & (AP_METHOD_BIT << i)) { - c->satisfy[i] = satisfy; - } - } - - return NULL; -} - -static const char *require(cmd_parms *cmd, void *c_, const char *arg) -{ - require_line *r; - core_dir_config *c = c_; - - if (!c->ap_requires) { - c->ap_requires = apr_array_make(cmd->pool, 2, sizeof(require_line)); - } - - r = (require_line *)apr_array_push(c->ap_requires); - r->requirement = apr_pstrdup(cmd->pool, arg); - r->method_mask = cmd->limited; - - return NULL; -} - -AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, - void *dummy, - const char *arg) -{ - const char *limited_methods = ap_getword(cmd->pool, &arg, '>'); - void *tog = cmd->cmd->cmd_data; - apr_int64_t limited = 0; - const char *errmsg; - - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - while (limited_methods[0]) { - char *method = ap_getword_conf(cmd->pool, &limited_methods); - int methnum; - - /* check for builtin or module registered method number */ - methnum = ap_method_number_of(method); - - if (methnum == M_TRACE && !tog) { - return "TRACE cannot be controlled by <Limit>, see TraceEnable"; - } - else if (methnum == M_INVALID) { - /* method has not been registered yet, but resorce restriction - * is always checked before method handling, so register it. - */ - methnum = ap_method_register(cmd->pool, method); - } - - limited |= (AP_METHOD_BIT << methnum); - } - - /* Killing two features with one function, - * if (tog == NULL) <Limit>, else <LimitExcept> - */ - cmd->limited = tog ? ~limited : limited; - - errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context); - - cmd->limited = -1; - - return errmsg; -} - -/* XXX: Bogus - need to do this differently (at least OS2/Netware suffer - * the same problem!!! - * We use this in <DirectoryMatch> and <FilesMatch>, to ensure that - * people don't get bitten by wrong-cased regex matches - */ - -#ifdef WIN32 -#define USE_ICASE REG_ICASE -#else -#define USE_ICASE 0 -#endif - -/* - * Report a missing-'>' syntax error. - */ -static char *unclosed_directive(cmd_parms *cmd) -{ - return apr_pstrcat(cmd->pool, cmd->cmd->name, - "> directive missing closing '>'", NULL); -} - -static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg) -{ - const char *errmsg; - const char *endp = ap_strrchr_c(arg, '>'); - int old_overrides = cmd->override; - char *old_path = cmd->path; - core_dir_config *conf; - ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool); - regex_t *r = NULL; - const command_rec *thiscmd = cmd->cmd; - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->pool, arg, endp - arg); - - if (!arg) { - if (thiscmd->cmd_data) - return "<DirectoryMatch > block must specify a path"; - else - return "<Directory > block must specify a path"; - } - - cmd->path = ap_getword_conf(cmd->pool, &arg); - cmd->override = OR_ALL|ACCESS_CONF; - - if (!strcmp(cmd->path, "~")) { - cmd->path = ap_getword_conf(cmd->pool, &arg); - if (!cmd->path) - return "<Directory ~ > block must specify a path"; - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE); - if (!r) { - return "Regex could not be compiled"; - } - } - else if (thiscmd->cmd_data) { /* <DirectoryMatch> */ - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE); - if (!r) { - return "Regex could not be compiled"; - } - } - else if (!strcmp(cmd->path, "/") == 0) - { - char *newpath; - - /* - * Ensure that the pathname is canonical, and append the trailing / - */ - apr_status_t rv = apr_filepath_merge(&newpath, NULL, cmd->path, - APR_FILEPATH_TRUENAME, cmd->pool); - if (rv != APR_SUCCESS && rv != APR_EPATHWILD) { - return apr_pstrcat(cmd->pool, "<Directory \"", cmd->path, - "\"> path is invalid.", NULL); - } - - cmd->path = newpath; - if (cmd->path[strlen(cmd->path) - 1] != '/') - cmd->path = apr_pstrcat(cmd->pool, cmd->path, "/", NULL); - } - - /* initialize our config and fetch it */ - conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path, - &core_module, cmd->pool); - - errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf); - if (errmsg != NULL) - return errmsg; - - conf->r = r; - conf->d = cmd->path; - conf->d_is_fnmatch = (apr_fnmatch_test(conf->d) != 0); - - /* Make this explicit - the "/" root has 0 elements, that is, we - * will always merge it, and it will always sort and merge first. - * All others are sorted and tested by the number of slashes. - */ - if (strcmp(conf->d, "/") == 0) - conf->d_components = 0; - else - conf->d_components = ap_count_dirs(conf->d); - - ap_add_per_dir_conf(cmd->server, new_dir_conf); - - if (*arg != '\0') { - return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, - "> arguments not (yet) supported.", NULL); - } - - cmd->path = old_path; - cmd->override = old_overrides; - - return NULL; -} - -static const char *urlsection(cmd_parms *cmd, void *mconfig, const char *arg) -{ - const char *errmsg; - const char *endp = ap_strrchr_c(arg, '>'); - int old_overrides = cmd->override; - char *old_path = cmd->path; - core_dir_config *conf; - regex_t *r = NULL; - const command_rec *thiscmd = cmd->cmd; - ap_conf_vector_t *new_url_conf = ap_create_per_dir_config(cmd->pool); - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->pool, arg, endp - arg); - - cmd->path = ap_getword_conf(cmd->pool, &arg); - cmd->override = OR_ALL|ACCESS_CONF; - - if (thiscmd->cmd_data) { /* <LocationMatch> */ - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED); - if (!r) { - return "Regex could not be compiled"; - } - } - else if (!strcmp(cmd->path, "~")) { - cmd->path = ap_getword_conf(cmd->pool, &arg); - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED); - if (!r) { - return "Regex could not be compiled"; - } - } - - /* initialize our config and fetch it */ - conf = ap_set_config_vectors(cmd->server, new_url_conf, cmd->path, - &core_module, cmd->pool); - - errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_url_conf); - if (errmsg != NULL) - return errmsg; - - conf->d = apr_pstrdup(cmd->pool, cmd->path); /* No mangling, please */ - conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0; - conf->r = r; - - ap_add_per_url_conf(cmd->server, new_url_conf); - - if (*arg != '\0') { - return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, - "> arguments not (yet) supported.", NULL); - } - - cmd->path = old_path; - cmd->override = old_overrides; - - return NULL; -} - -static const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg) -{ - const char *errmsg; - const char *endp = ap_strrchr_c(arg, '>'); - int old_overrides = cmd->override; - char *old_path = cmd->path; - core_dir_config *conf; - regex_t *r = NULL; - const command_rec *thiscmd = cmd->cmd; - core_dir_config *c = mconfig; - ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool); - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_LOCATION); - - if (err != NULL) { - return err; - } - - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->pool, arg, endp - arg); - - cmd->path = ap_getword_conf(cmd->pool, &arg); - /* Only if not an .htaccess file */ - if (!old_path) { - cmd->override = OR_ALL|ACCESS_CONF; - } - - if (thiscmd->cmd_data) { /* <FilesMatch> */ - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE); - if (!r) { - return "Regex could not be compiled"; - } - } - else if (!strcmp(cmd->path, "~")) { - cmd->path = ap_getword_conf(cmd->pool, &arg); - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE); - if (!r) { - return "Regex could not be compiled"; - } - } - else { - char *newpath; - /* Ensure that the pathname is canonical, but we - * can't test the case/aliases without a fixed path */ - if (apr_filepath_merge(&newpath, "", cmd->path, - 0, cmd->pool) != APR_SUCCESS) - return apr_pstrcat(cmd->pool, "<Files \"", cmd->path, - "\"> is invalid.", NULL); - cmd->path = newpath; - } - - /* initialize our config and fetch it */ - conf = ap_set_config_vectors(cmd->server, new_file_conf, cmd->path, - &core_module, cmd->pool); - - errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_file_conf); - if (errmsg != NULL) - return errmsg; - - conf->d = cmd->path; - conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0; - conf->r = r; - - ap_add_file_conf(c, new_file_conf); - - if (*arg != '\0') { - return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, - "> arguments not (yet) supported.", NULL); - } - - cmd->path = old_path; - cmd->override = old_overrides; - - return NULL; -} - -static const char *start_ifmod(cmd_parms *cmd, void *mconfig, const char *arg) -{ - const char *endp = ap_strrchr_c(arg, '>'); - int not = (arg[0] == '!'); - module *found; - - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->pool, arg, endp - arg); - - if (not) { - arg++; - } - - found = ap_find_linked_module(arg); - - if ((!not && found) || (not && !found)) { - ap_directive_t *parent = NULL; - ap_directive_t *current = NULL; - const char *retval; - - retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, - ¤t, &parent, "<IfModule"); - *(ap_directive_t **)mconfig = current; - return retval; - } - else { - *(ap_directive_t **)mconfig = NULL; - return ap_soak_end_container(cmd, "<IfModule"); - } -} - -AP_DECLARE(int) ap_exists_config_define(const char *name) -{ - char **defines; - int i; - - defines = (char **)ap_server_config_defines->elts; - for (i = 0; i < ap_server_config_defines->nelts; i++) { - if (strcmp(defines[i], name) == 0) { - return 1; - } - } - - return 0; -} - -static const char *start_ifdefine(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *endp; - int defined; - int not = 0; - - endp = ap_strrchr_c(arg, '>'); - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->pool, arg, endp - arg); - - if (arg[0] == '!') { - not = 1; - arg++; - } - - defined = ap_exists_config_define(arg); - if ((!not && defined) || (not && !defined)) { - ap_directive_t *parent = NULL; - ap_directive_t *current = NULL; - const char *retval; - - retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, - ¤t, &parent, "<IfDefine"); - *(ap_directive_t **)dummy = current; - return retval; - } - else { - *(ap_directive_t **)dummy = NULL; - return ap_soak_end_container(cmd, "<IfDefine"); - } -} - -/* httpd.conf commands... beginning with the <VirtualHost> business */ - -static const char *virtualhost_section(cmd_parms *cmd, void *dummy, - const char *arg) -{ - server_rec *main_server = cmd->server, *s; - const char *errmsg; - const char *endp = ap_strrchr_c(arg, '>'); - apr_pool_t *p = cmd->pool; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->pool, arg, endp - arg); - - /* FIXME: There's another feature waiting to happen here -- since you - can now put multiple addresses/names on a single <VirtualHost> - you might want to use it to group common definitions and then - define other "subhosts" with their individual differences. But - personally I'd rather just do it with a macro preprocessor. -djg */ - if (main_server->is_virtual) { - return "<VirtualHost> doesn't nest!"; - } - - errmsg = ap_init_virtual_host(p, arg, main_server, &s); - if (errmsg) { - return errmsg; - } - - s->next = main_server->next; - main_server->next = s; - - s->defn_name = cmd->directive->filename; - s->defn_line_number = cmd->directive->line_num; - - cmd->server = s; - - errmsg = ap_walk_config(cmd->directive->first_child, cmd, - s->lookup_defaults); - - cmd->server = main_server; - - return errmsg; -} - -static const char *set_server_alias(cmd_parms *cmd, void *dummy, - const char *arg) -{ - if (!cmd->server->names) { - return "ServerAlias only used in <VirtualHost>"; - } - - while (*arg) { - char **item, *name = ap_getword_conf(cmd->pool, &arg); - - if (ap_is_matchexp(name)) { - item = (char **)apr_array_push(cmd->server->wild_names); - } - else { - item = (char **)apr_array_push(cmd->server->names); - } - - *item = name; - } - - return NULL; -} - -static const char *set_server_string_slot(cmd_parms *cmd, void *dummy, - const char *arg) -{ - /* This one's pretty generic... */ - - int offset = (int)(long)cmd->info; - char *struct_ptr = (char *)cmd->server; - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - *(const char **)(struct_ptr + offset) = arg; - return NULL; -} - -static const char *server_hostname_port(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - const char *portstr; - int port; - - if (err != NULL) { - return err; - } - - portstr = ap_strchr_c(arg, ':'); - if (portstr) { - cmd->server->server_hostname = apr_pstrndup(cmd->pool, arg, - portstr - arg); - portstr++; - port = atoi(portstr); - if (port <= 0 || port >= 65536) { /* 65536 == 1<<16 */ - return apr_pstrcat(cmd->temp_pool, "The port number \"", arg, - "\" is outside the appropriate range " - "(i.e., 1..65535).", NULL); - } - } - else { - cmd->server->server_hostname = apr_pstrdup(cmd->pool, arg); - port = 0; - } - - cmd->server->port = port; - return NULL; -} - -static const char *set_signature_flag(cmd_parms *cmd, void *d_, - const char *arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - if (strcasecmp(arg, "On") == 0) { - d->server_signature = srv_sig_on; - } - else if (strcasecmp(arg, "Off") == 0) { - d->server_signature = srv_sig_off; - } - else if (strcasecmp(arg, "EMail") == 0) { - d->server_signature = srv_sig_withmail; - } - else { - return "ServerSignature: use one of: off | on | email"; - } - - return NULL; -} - -static const char *set_server_root(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - if ((apr_filepath_merge((char**)&ap_server_root, NULL, arg, - APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS) - || !ap_is_directory(cmd->pool, ap_server_root)) { - return "ServerRoot must be a valid directory"; - } - - return NULL; -} - -static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - cmd->server->timeout = apr_time_from_sec(atoi(arg)); - return NULL; -} - -static const char *set_idcheck(cmd_parms *cmd, void *d_, int arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - d->do_rfc1413 = arg != 0; - return NULL; -} - -static const char *set_allow2f(cmd_parms *cmd, void *d_, int arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - d->allow_encoded_slashes = arg != 0; - return NULL; -} - -static const char *set_hostname_lookups(cmd_parms *cmd, void *d_, - const char *arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - if (!strcasecmp(arg, "on")) { - d->hostname_lookups = HOSTNAME_LOOKUP_ON; - } - else if (!strcasecmp(arg, "off")) { - d->hostname_lookups = HOSTNAME_LOOKUP_OFF; - } - else if (!strcasecmp(arg, "double")) { - d->hostname_lookups = HOSTNAME_LOOKUP_DOUBLE; - } - else { - return "parameter must be 'on', 'off', or 'double'"; - } - - return NULL; -} - -static const char *set_serverpath(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - cmd->server->path = arg; - cmd->server->pathlen = strlen(arg); - return NULL; -} - -static const char *set_content_md5(cmd_parms *cmd, void *d_, int arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - d->content_md5 = arg != 0; - return NULL; -} - -static const char *set_accept_path_info(cmd_parms *cmd, void *d_, const char *arg) -{ - core_dir_config *d = d_; - - if (strcasecmp(arg, "on") == 0) { - d->accept_path_info = AP_REQ_ACCEPT_PATH_INFO; - } - else if (strcasecmp(arg, "off") == 0) { - d->accept_path_info = AP_REQ_REJECT_PATH_INFO; - } - else if (strcasecmp(arg, "default") == 0) { - d->accept_path_info = AP_REQ_DEFAULT_PATH_INFO; - } - else { - return "AcceptPathInfo must be set to on, off or default"; - } - - return NULL; -} - -static const char *set_use_canonical_name(cmd_parms *cmd, void *d_, - const char *arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - if (strcasecmp(arg, "on") == 0) { - d->use_canonical_name = USE_CANONICAL_NAME_ON; - } - else if (strcasecmp(arg, "off") == 0) { - d->use_canonical_name = USE_CANONICAL_NAME_OFF; - } - else if (strcasecmp(arg, "dns") == 0) { - d->use_canonical_name = USE_CANONICAL_NAME_DNS; - } - else { - return "parameter must be 'on', 'off', or 'dns'"; - } - - return NULL; -} - - -static const char *include_config (cmd_parms *cmd, void *dummy, - const char *name) -{ - ap_directive_t *conftree = NULL; - const char* conffile; - unsigned *recursion; - void *data; - - apr_pool_userdata_get(&data, "ap_include_sentinel", cmd->pool); - if (data) { - recursion = data; - } - else { - data = recursion = apr_palloc(cmd->pool, sizeof(*recursion)); - *recursion = 0; - apr_pool_userdata_setn(data, "ap_include_sentinel", NULL, cmd->pool); - } - - if (++*recursion > AP_MAX_INCLUDE_DEPTH) { - *recursion = 0; - return apr_psprintf(cmd->pool, "Exceeded maximum include depth of %u. " - "You have probably a recursion somewhere.", - AP_MAX_INCLUDE_DEPTH); - } - - conffile = ap_server_root_relative(cmd->pool, name); - if (!conffile) { - *recursion = 0; - return apr_pstrcat(cmd->pool, "Invalid Include path ", - name, NULL); - } - - ap_process_resource_config(cmd->server, conffile, - &conftree, cmd->pool, cmd->temp_pool); - *(ap_directive_t **)dummy = conftree; - - /* recursion level done */ - if (*recursion) { - --*recursion; - } - - return NULL; -} - -static const char *set_loglevel(cmd_parms *cmd, void *dummy, const char *arg) -{ - char *str; - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - if ((str = ap_getword_conf(cmd->pool, &arg))) { - if (!strcasecmp(str, "emerg")) { - cmd->server->loglevel = APLOG_EMERG; - } - else if (!strcasecmp(str, "alert")) { - cmd->server->loglevel = APLOG_ALERT; - } - else if (!strcasecmp(str, "crit")) { - cmd->server->loglevel = APLOG_CRIT; - } - else if (!strcasecmp(str, "error")) { - cmd->server->loglevel = APLOG_ERR; - } - else if (!strcasecmp(str, "warn")) { - cmd->server->loglevel = APLOG_WARNING; - } - else if (!strcasecmp(str, "notice")) { - cmd->server->loglevel = APLOG_NOTICE; - } - else if (!strcasecmp(str, "info")) { - cmd->server->loglevel = APLOG_INFO; - } - else if (!strcasecmp(str, "debug")) { - cmd->server->loglevel = APLOG_DEBUG; - } - else { - return "LogLevel requires level keyword: one of " - "emerg/alert/crit/error/warn/notice/info/debug"; - } - } - else { - return "LogLevel requires level keyword"; - } - - return NULL; -} - -AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r) -{ - char sport[20]; - core_dir_config *conf; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - if ((conf->server_signature == srv_sig_off) - || (conf->server_signature == srv_sig_unset)) { - return ""; - } - - apr_snprintf(sport, sizeof sport, "%u", (unsigned) ap_get_server_port(r)); - - if (conf->server_signature == srv_sig_withmail) { - return apr_pstrcat(r->pool, prefix, "<address>", - ap_get_server_version(), - " Server at <a href=\"", - ap_is_url(r->server->server_admin) ? "" : "mailto:", - ap_escape_html(r->pool, r->server->server_admin), - "\">", - ap_escape_html(r->pool, ap_get_server_name(r)), - "</a> Port ", sport, - "</address>\n", NULL); - } - - return apr_pstrcat(r->pool, prefix, "<address>", ap_get_server_version(), - " Server at ", - ap_escape_html(r->pool, ap_get_server_name(r)), - " Port ", sport, - "</address>\n", NULL); -} - -/* - * Load an authorisation realm into our location configuration, applying the - * usual rules that apply to realms. - */ -static const char *set_authname(cmd_parms *cmd, void *mconfig, - const char *word1) -{ - core_dir_config *aconfig = (core_dir_config *)mconfig; - - aconfig->ap_auth_name = ap_escape_quotes(cmd->pool, word1); - return NULL; -} - -#ifdef _OSD_POSIX /* BS2000 Logon Passwd file */ -static const char *set_bs2000_account(cmd_parms *cmd, void *dummy, char *name) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - return os_set_account(cmd->pool, name); -} -#endif /*_OSD_POSIX*/ - -/* - * Handle a request to include the server's OS platform in the Server - * response header field (the ServerTokens directive). Unfortunately - * this requires a new global in order to communicate the setting back to - * http_main so it can insert the information in the right place in the - * string. - */ - -static char *server_version = NULL; -static int version_locked = 0; - -enum server_token_type { - SrvTk_MAJOR, /* eg: Apache/2 */ - SrvTk_MINOR, /* eg. Apache/2.0 */ - SrvTk_MINIMAL, /* eg: Apache/2.0.41 */ - SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */ - SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */ - SrvTk_PRODUCT_ONLY /* eg: Apache */ -}; -static enum server_token_type ap_server_tokens = SrvTk_FULL; - -static apr_status_t reset_version(void *dummy) -{ - version_locked = 0; - ap_server_tokens = SrvTk_FULL; - server_version = NULL; - return APR_SUCCESS; -} - -AP_DECLARE(void) ap_get_server_revision(ap_version_t *version) -{ - version->major = AP_SERVER_MAJORVERSION_NUMBER; - version->minor = AP_SERVER_MINORVERSION_NUMBER; - version->patch = AP_SERVER_PATCHLEVEL_NUMBER; - version->add_string = AP_SERVER_ADD_STRING; -} - -AP_DECLARE(const char *) ap_get_server_version(void) -{ - return (server_version ? server_version : AP_SERVER_BASEVERSION); -} - -AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component) -{ - if (! version_locked) { - /* - * If the version string is null, register our cleanup to reset the - * pointer on pool destruction. We also know that, if NULL, - * we are adding the original SERVER_BASEVERSION string. - */ - if (server_version == NULL) { - apr_pool_cleanup_register(pconf, NULL, reset_version, - apr_pool_cleanup_null); - server_version = apr_pstrdup(pconf, component); - } - else { - /* - * Tack the given component identifier to the end of - * the existing string. - */ - server_version = apr_pstrcat(pconf, server_version, " ", - component, NULL); - } - } -} - -/* - * This routine adds the real server base identity to the version string, - * and then locks out changes until the next reconfig. - */ -static void ap_set_version(apr_pool_t *pconf) -{ - if (ap_server_tokens == SrvTk_PRODUCT_ONLY) { - ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT); - } - else if (ap_server_tokens == SrvTk_MINIMAL) { - ap_add_version_component(pconf, AP_SERVER_BASEVERSION); - } - else if (ap_server_tokens == SrvTk_MINOR) { - ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MINORREVISION); - } - else if (ap_server_tokens == SrvTk_MAJOR) { - ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION); - } - else { - ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")"); - } - - /* - * Lock the server_version string if we're not displaying - * the full set of tokens - */ - if (ap_server_tokens != SrvTk_FULL) { - version_locked++; - } -} - -static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - if (!strcasecmp(arg, "OS")) { - ap_server_tokens = SrvTk_OS; - } - else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) { - ap_server_tokens = SrvTk_MINIMAL; - } - else if (!strcasecmp(arg, "Major")) { - ap_server_tokens = SrvTk_MAJOR; - } - else if (!strcasecmp(arg, "Minor") ) { - ap_server_tokens = SrvTk_MINOR; - } - else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) { - ap_server_tokens = SrvTk_PRODUCT_ONLY; - } - else { - ap_server_tokens = SrvTk_FULL; - } - - return NULL; -} - -static const char *set_limit_req_line(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - int lim; - - if (err != NULL) { - return err; - } - - lim = atoi(arg); - if (lim < 0) { - return apr_pstrcat(cmd->temp_pool, "LimitRequestLine \"", arg, - "\" must be a non-negative integer", NULL); - } - - cmd->server->limit_req_line = lim; - return NULL; -} - -static const char *set_limit_req_fieldsize(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - int lim; - - if (err != NULL) { - return err; - } - - lim = atoi(arg); - if (lim < 0) { - return apr_pstrcat(cmd->temp_pool, "LimitRequestFieldsize \"", arg, - "\" must be a non-negative integer", - NULL); - } - - cmd->server->limit_req_fieldsize = lim; - return NULL; -} - -static const char *set_limit_req_fields(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - int lim; - - if (err != NULL) { - return err; - } - - lim = atoi(arg); - if (lim < 0) { - return apr_pstrcat(cmd->temp_pool, "LimitRequestFields \"", arg, - "\" must be a non-negative integer (0 = no limit)", - NULL); - } - - cmd->server->limit_req_fields = lim; - return NULL; -} - -static const char *set_limit_req_body(cmd_parms *cmd, void *conf_, - const char *arg) -{ - core_dir_config *conf = conf_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - char *errp; - - if (err != NULL) { - return err; - } - - /* WTF: If strtoul is not portable, then write a replacement. - * Instead we have an idiotic define in httpd.h that prevents - * it from being used even when it is available. Sheesh. - */ - conf->limit_req_body = (apr_off_t)strtol(arg, &errp, 10); - if (*errp != '\0') { - return "LimitRequestBody requires a non-negative integer."; - } - - return NULL; -} - -static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_, - const char *arg) -{ - core_dir_config *conf = conf_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - conf->limit_xml_body = atol(arg); - if (conf->limit_xml_body < 0) - return "LimitXMLRequestBody requires a non-negative integer."; - - return NULL; -} - -AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r) -{ - core_dir_config *conf; - - conf = ap_get_module_config(r->per_dir_config, &core_module); - if (conf->limit_xml_body == AP_LIMIT_UNSET) - return AP_DEFAULT_LIMIT_XML_BODY; - - return (size_t)conf->limit_xml_body; -} - -#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC) -static const char *no_set_limit(cmd_parms *cmd, void *conf_, - const char *arg, const char *arg2) -{ - ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, - "%s not supported on this platform", cmd->cmd->name); - - return NULL; -} -#endif - -#ifdef RLIMIT_CPU -static const char *set_limit_cpu(cmd_parms *cmd, void *conf_, - const char *arg, const char *arg2) -{ - core_dir_config *conf = conf_; - - unixd_set_rlimit(cmd, &conf->limit_cpu, arg, arg2, RLIMIT_CPU); - return NULL; -} -#endif - -#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) -static const char *set_limit_mem(cmd_parms *cmd, void *conf_, - const char *arg, const char * arg2) -{ - core_dir_config *conf = conf_; - -#if defined(RLIMIT_AS) - unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2 ,RLIMIT_AS); -#elif defined(RLIMIT_DATA) - unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_DATA); -#elif defined(RLIMIT_VMEM) - unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_VMEM); -#endif - - return NULL; -} -#endif - -#ifdef RLIMIT_NPROC -static const char *set_limit_nproc(cmd_parms *cmd, void *conf_, - const char *arg, const char * arg2) -{ - core_dir_config *conf = conf_; - - unixd_set_rlimit(cmd, &conf->limit_nproc, arg, arg2, RLIMIT_NPROC); - return NULL; -} -#endif - -static const char *set_recursion_limit(cmd_parms *cmd, void *dummy, - const char *arg1, const char *arg2) -{ - core_server_config *conf = ap_get_module_config(cmd->server->module_config, - &core_module); - int limit = atoi(arg1); - - if (limit <= 0) { - return "The recursion limit must be greater than zero."; - } - if (limit < 4) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, - "Limiting internal redirects to very low numbers may " - "cause normal requests to fail."); - } - - conf->redirect_limit = limit; - - if (arg2) { - limit = atoi(arg2); - - if (limit <= 0) { - return "The recursion limit must be greater than zero."; - } - if (limit < 4) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, - "Limiting the subrequest depth to a very low level may" - " cause normal requests to fail."); - } - } - - conf->subreq_limit = limit; - - return NULL; -} - -static void log_backtrace(const request_rec *r) -{ - const request_rec *top = r; - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "r->uri = %s", r->uri ? r->uri : "(unexpectedly NULL)"); - - while (top && (top->prev || top->main)) { - if (top->prev) { - top = top->prev; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "redirected from r->uri = %s", - top->uri ? top->uri : "(unexpectedly NULL)"); - } - - if (!top->prev && top->main) { - top = top->main; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "subrequested from r->uri = %s", - top->uri ? top->uri : "(unexpectedly NULL)"); - } - } -} - -/* - * check whether redirect limit is reached - */ -AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r) -{ - core_server_config *conf = ap_get_module_config(r->server->module_config, - &core_module); - const request_rec *top = r; - int redirects = 0, subreqs = 0; - int rlimit = conf->redirect_limit - ? conf->redirect_limit - : AP_DEFAULT_MAX_INTERNAL_REDIRECTS; - int slimit = conf->subreq_limit - ? conf->subreq_limit - : AP_DEFAULT_MAX_SUBREQ_DEPTH; - - - while (top->prev || top->main) { - if (top->prev) { - if (++redirects >= rlimit) { - /* uuh, too much. */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Request exceeded the limit of %d internal " - "redirects due to probable configuration error. " - "Use 'LimitInternalRecursion' to increase the " - "limit if necessary. Use 'LogLevel debug' to get " - "a backtrace.", rlimit); - - /* post backtrace */ - log_backtrace(r); - - /* return failure */ - return 1; - } - - top = top->prev; - } - - if (!top->prev && top->main) { - if (++subreqs >= slimit) { - /* uuh, too much. */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Request exceeded the limit of %d subrequest " - "nesting levels due to probable confguration " - "error. Use 'LimitInternalRecursion' to increase " - "the limit if necessary. Use 'LogLevel debug' to " - "get a backtrace.", slimit); - - /* post backtrace */ - log_backtrace(r); - - /* return failure */ - return 1; - } - - top = top->main; - } - } - - /* recursion state: ok */ - return 0; -} - -static const char *add_ct_output_filters(cmd_parms *cmd, void *conf_, - const char *arg, const char *arg2) -{ - core_dir_config *conf = conf_; - ap_filter_rec_t *old, *new = NULL; - const char *filter_name; - - if (!conf->ct_output_filters) { - conf->ct_output_filters = apr_hash_make(cmd->pool); - old = NULL; - } - else { - old = (ap_filter_rec_t*) apr_hash_get(conf->ct_output_filters, arg2, - APR_HASH_KEY_STRING); - } - - while (*arg && - (filter_name = ap_getword(cmd->pool, &arg, ';')) && - strcmp(filter_name, "")) { - new = apr_pcalloc(cmd->pool, sizeof(ap_filter_rec_t)); - new->name = filter_name; - - /* We found something, so let's append it. */ - if (old) { - new->next = old; - } - old = new; - } - - if (!new) { - return "invalid filter name"; - } - - apr_hash_set(conf->ct_output_filters, arg2, APR_HASH_KEY_STRING, new); - - return NULL; -} -/* - * Insert filters requested by the AddOutputFilterByType - * configuration directive. We cannot add filters based - * on content-type until after the handler has started - * to run. Only then do we reliably know the content-type. - */ -void ap_add_output_filters_by_type(request_rec *r) -{ - core_dir_config *conf; - const char *ctype, *ctypes; - - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - /* We can't do anything with proxy requests, no content-types or if - * we don't have a filter configured. - */ - if (r->proxyreq != PROXYREQ_NONE || !r->content_type || - !conf->ct_output_filters) { - return; - } - - ctypes = r->content_type; - - /* We must be able to handle decorated content-types. */ - while (*ctypes && (ctype = ap_getword(r->pool, &ctypes, ';'))) { - ap_filter_rec_t *ct_filter; - ct_filter = apr_hash_get(conf->ct_output_filters, ctype, - APR_HASH_KEY_STRING); - while (ct_filter) { - ap_add_output_filter(ct_filter->name, NULL, r, r->connection); - ct_filter = ct_filter->next; - } - } - - return; -} - -static apr_status_t writev_it_all(apr_socket_t *s, - struct iovec *vec, int nvec, - apr_size_t len, apr_size_t *nbytes) -{ - apr_size_t bytes_written = 0; - apr_status_t rv; - apr_size_t n = len; - int i = 0; - - *nbytes = 0; - - /* XXX handle checking for non-blocking socket */ - while (bytes_written != len) { - rv = apr_sendv(s, vec + i, nvec - i, &n); - bytes_written += n; - if (rv != APR_SUCCESS) - return rv; - - *nbytes += n; - - /* If the write did not complete, adjust the iovecs and issue - * apr_sendv again - */ - if (bytes_written < len) { - /* Skip over the vectors that have already been written */ - apr_size_t cnt = vec[i].iov_len; - while (n >= cnt && i + 1 < nvec) { - i++; - cnt += vec[i].iov_len; - } - - if (n < cnt) { - /* Handle partial write of vec i */ - vec[i].iov_base = (char *) vec[i].iov_base + - (vec[i].iov_len - (cnt - n)); - vec[i].iov_len = cnt -n; - } - } - - n = len - bytes_written; - } - - return APR_SUCCESS; -} - -/* sendfile_it_all() - * send the entire file using sendfile() - * handle partial writes - * return only when all bytes have been sent or an error is encountered. - */ - -#if APR_HAS_SENDFILE -static apr_status_t sendfile_it_all(core_net_rec *c, - apr_file_t *fd, - apr_hdtr_t *hdtr, - apr_off_t file_offset, - apr_size_t file_bytes_left, - apr_size_t total_bytes_left, - apr_size_t *bytes_sent, - apr_int32_t flags) -{ - apr_status_t rv; -#ifdef AP_DEBUG - apr_interval_time_t timeout = 0; -#endif - - AP_DEBUG_ASSERT((apr_socket_timeout_get(c->client_socket, &timeout) - == APR_SUCCESS) - && timeout > 0); /* socket must be in timeout mode */ - - /* Reset the bytes_sent field */ - *bytes_sent = 0; - - do { - apr_size_t tmplen = file_bytes_left; - - rv = apr_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen, - flags); - *bytes_sent += tmplen; - total_bytes_left -= tmplen; - if (!total_bytes_left || rv != APR_SUCCESS) { - return rv; /* normal case & error exit */ - } - - AP_DEBUG_ASSERT(total_bytes_left > 0 && tmplen > 0); - - /* partial write, oooh noooo... - * Skip over any header data which was written - */ - while (tmplen && hdtr->numheaders) { - if (tmplen >= hdtr->headers[0].iov_len) { - tmplen -= hdtr->headers[0].iov_len; - --hdtr->numheaders; - ++hdtr->headers; - } - else { - char *iov_base = (char *)hdtr->headers[0].iov_base; - - hdtr->headers[0].iov_len -= tmplen; - iov_base += tmplen; - hdtr->headers[0].iov_base = iov_base; - tmplen = 0; - } - } - - /* Skip over any file data which was written */ - - if (tmplen <= file_bytes_left) { - file_offset += tmplen; - file_bytes_left -= tmplen; - continue; - } - - tmplen -= file_bytes_left; - file_bytes_left = 0; - file_offset = 0; - - /* Skip over any trailer data which was written */ - - while (tmplen && hdtr->numtrailers) { - if (tmplen >= hdtr->trailers[0].iov_len) { - tmplen -= hdtr->trailers[0].iov_len; - --hdtr->numtrailers; - ++hdtr->trailers; - } - else { - char *iov_base = (char *)hdtr->trailers[0].iov_base; - - hdtr->trailers[0].iov_len -= tmplen; - iov_base += tmplen; - hdtr->trailers[0].iov_base = iov_base; - tmplen = 0; - } - } - } while (1); -} -#endif - -/* - * emulate_sendfile() - * Sends the contents of file fd along with header/trailer bytes, if any, - * to the network. emulate_sendfile will return only when all the bytes have been - * sent (i.e., it handles partial writes) or on a network error condition. - */ -static apr_status_t emulate_sendfile(core_net_rec *c, apr_file_t *fd, - apr_hdtr_t *hdtr, apr_off_t offset, - apr_size_t length, apr_size_t *nbytes) -{ - apr_status_t rv = APR_SUCCESS; - apr_int32_t togo; /* Remaining number of bytes in the file to send */ - apr_size_t sendlen = 0; - apr_size_t bytes_sent; - apr_int32_t i; - apr_off_t o; /* Track the file offset for partial writes */ - char buffer[8192]; - - *nbytes = 0; - - /* Send the headers - * writev_it_all handles partial writes. - * XXX: optimization... if headers are less than MIN_WRITE_SIZE, copy - * them into buffer - */ - if (hdtr && hdtr->numheaders > 0 ) { - for (i = 0; i < hdtr->numheaders; i++) { - sendlen += hdtr->headers[i].iov_len; - } - - rv = writev_it_all(c->client_socket, hdtr->headers, hdtr->numheaders, - sendlen, &bytes_sent); - if (rv == APR_SUCCESS) - *nbytes += bytes_sent; /* track total bytes sent */ - } - - /* Seek the file to 'offset' */ - if (offset >= 0 && rv == APR_SUCCESS) { - rv = apr_file_seek(fd, APR_SET, &offset); - } - - /* Send the file, making sure to handle partial writes */ - togo = length; - while (rv == APR_SUCCESS && togo) { - sendlen = togo > sizeof(buffer) ? sizeof(buffer) : togo; - o = 0; - rv = apr_file_read(fd, buffer, &sendlen); - while (rv == APR_SUCCESS && sendlen) { - bytes_sent = sendlen; - rv = apr_send(c->client_socket, &buffer[o], &bytes_sent); - if (rv == APR_SUCCESS) { - sendlen -= bytes_sent; /* sendlen != bytes_sent ==> partial write */ - o += bytes_sent; /* o is where we are in the buffer */ - *nbytes += bytes_sent; - togo -= bytes_sent; /* track how much of the file we've sent */ - } - } - } - - /* Send the trailers - * XXX: optimization... if it will fit, send this on the last send in the - * loop above - */ - sendlen = 0; - if ( rv == APR_SUCCESS && hdtr && hdtr->numtrailers > 0 ) { - for (i = 0; i < hdtr->numtrailers; i++) { - sendlen += hdtr->trailers[i].iov_len; - } - rv = writev_it_all(c->client_socket, hdtr->trailers, hdtr->numtrailers, - sendlen, &bytes_sent); - if (rv == APR_SUCCESS) - *nbytes += bytes_sent; - } - - return rv; -} - -static const char *set_trace_enable(cmd_parms *cmd, void *dummy, - const char *arg1) -{ - core_server_config *conf = ap_get_module_config(cmd->server->module_config, - &core_module); - - if (strcasecmp(arg1, "on") == 0) { - conf->trace_enable = AP_TRACE_ENABLE; - } - else if (strcasecmp(arg1, "off") == 0) { - conf->trace_enable = AP_TRACE_DISABLE; - } - else if (strcasecmp(arg1, "extended") == 0) { - conf->trace_enable = AP_TRACE_EXTENDED; - } - else { - return "TraceEnable must be one of 'on', 'off', or 'extended'"; - } - - return NULL; -} - -/* Note --- ErrorDocument will now work from .htaccess files. - * The AllowOverride of Fileinfo allows webmasters to turn it off - */ - -static const command_rec core_cmds[] = { - -/* Old access config file commands */ - -AP_INIT_RAW_ARGS("<Directory", dirsection, NULL, RSRC_CONF, - "Container for directives affecting resources located in the specified " - "directories"), -AP_INIT_RAW_ARGS("<Location", urlsection, NULL, RSRC_CONF, - "Container for directives affecting resources accessed through the " - "specified URL paths"), -AP_INIT_RAW_ARGS("<VirtualHost", virtualhost_section, NULL, RSRC_CONF, - "Container to map directives to a particular virtual host, takes one or " - "more host addresses"), -AP_INIT_RAW_ARGS("<Files", filesection, NULL, OR_ALL, - "Container for directives affecting files matching specified patterns"), -AP_INIT_RAW_ARGS("<Limit", ap_limit_section, NULL, OR_ALL, - "Container for authentication directives when accessed using specified HTTP " - "methods"), -AP_INIT_RAW_ARGS("<LimitExcept", ap_limit_section, (void*)1, OR_ALL, - "Container for authentication directives to be applied when any HTTP " - "method other than those specified is used to access the resource"), -AP_INIT_TAKE1("<IfModule", start_ifmod, NULL, EXEC_ON_READ | OR_ALL, - "Container for directives based on existance of specified modules"), -AP_INIT_TAKE1("<IfDefine", start_ifdefine, NULL, EXEC_ON_READ | OR_ALL, - "Container for directives based on existance of command line defines"), -AP_INIT_RAW_ARGS("<DirectoryMatch", dirsection, (void*)1, RSRC_CONF, - "Container for directives affecting resources located in the " - "specified directories"), -AP_INIT_RAW_ARGS("<LocationMatch", urlsection, (void*)1, RSRC_CONF, - "Container for directives affecting resources accessed through the " - "specified URL paths"), -AP_INIT_RAW_ARGS("<FilesMatch", filesection, (void*)1, OR_ALL, - "Container for directives affecting files matching specified patterns"), -AP_INIT_TAKE1("AuthType", ap_set_string_slot, - (void*)APR_OFFSETOF(core_dir_config, ap_auth_type), OR_AUTHCFG, - "An HTTP authorization type (e.g., \"Basic\")"), -AP_INIT_TAKE1("AuthName", set_authname, NULL, OR_AUTHCFG, - "The authentication realm (e.g. \"Members Only\")"), -AP_INIT_RAW_ARGS("Require", require, NULL, OR_AUTHCFG, - "Selects which authenticated users or groups may access a protected space"), -AP_INIT_TAKE1("Satisfy", satisfy, NULL, OR_AUTHCFG, - "access policy if both allow and require used ('all' or 'any')"), -#ifdef GPROF -AP_INIT_TAKE1("GprofDir", set_gprof_dir, NULL, RSRC_CONF, - "Directory to plop gmon.out files"), -#endif -AP_INIT_TAKE1("AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO, - "The name of the default charset to add to any Content-Type without one or 'Off' to disable"), -AP_INIT_TAKE1("AcceptPathInfo", set_accept_path_info, NULL, OR_FILEINFO, - "Set to on or off for PATH_INFO to be accepted by handlers, or default for the per-handler preference"), - -/* Old resource config file commands */ - -AP_INIT_RAW_ARGS("AccessFileName", set_access_name, NULL, RSRC_CONF, - "Name(s) of per-directory config files (default: .htaccess)"), -AP_INIT_TAKE1("DocumentRoot", set_document_root, NULL, RSRC_CONF, - "Root directory of the document tree"), -AP_INIT_TAKE2("ErrorDocument", set_error_document, NULL, OR_FILEINFO, - "Change responses for HTTP errors"), -AP_INIT_RAW_ARGS("AllowOverride", set_override, NULL, ACCESS_CONF, - "Controls what groups of directives can be configured by per-directory " - "config files"), -AP_INIT_RAW_ARGS("Options", set_options, NULL, OR_OPTIONS, - "Set a number of attributes for a given directory"), -AP_INIT_TAKE1("DefaultType", ap_set_string_slot, - (void*)APR_OFFSETOF(core_dir_config, ap_default_type), - OR_FILEINFO, "the default MIME type for untypable files"), -AP_INIT_RAW_ARGS("FileETag", set_etag_bits, NULL, OR_FILEINFO, - "Specify components used to construct a file's ETag"), -AP_INIT_TAKE1("EnableMMAP", set_enable_mmap, NULL, OR_FILEINFO, - "Controls whether memory-mapping may be used to read files"), -AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO, - "Controls whether sendfile may be used to transmit files"), - -/* Old server config file commands */ - -AP_INIT_TAKE1("Port", ap_set_deprecated, NULL, RSRC_CONF, - "Port was replaced with Listen in Apache 2.0"), -AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL, - ACCESS_CONF|RSRC_CONF, - "\"on\" to enable, \"off\" to disable reverse DNS lookups, or \"double\" to " - "enable double-reverse DNS lookups"), -AP_INIT_TAKE1("ServerAdmin", set_server_string_slot, - (void *)APR_OFFSETOF(server_rec, server_admin), RSRC_CONF, - "The email address of the server administrator"), -AP_INIT_TAKE1("ServerName", server_hostname_port, NULL, RSRC_CONF, - "The hostname and port of the server"), -AP_INIT_TAKE1("ServerSignature", set_signature_flag, NULL, OR_ALL, - "En-/disable server signature (on|off|email)"), -AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF | EXEC_ON_READ, - "Common directory of server-related files (logs, confs, etc.)"), -AP_INIT_TAKE1("ErrorLog", set_server_string_slot, - (void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF, - "The filename of the error log"), -AP_INIT_RAW_ARGS("ServerAlias", set_server_alias, NULL, RSRC_CONF, - "A name or names alternately used to access the server"), -AP_INIT_TAKE1("ServerPath", set_serverpath, NULL, RSRC_CONF, - "The pathname the server can be reached at"), -AP_INIT_TAKE1("Timeout", set_timeout, NULL, RSRC_CONF, - "Timeout duration (sec)"), -AP_INIT_FLAG("IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, - "Enable identd (RFC 1413) user lookups - SLOW"), -AP_INIT_FLAG("ContentDigest", set_content_md5, NULL, OR_OPTIONS, - "whether or not to send a Content-MD5 header with each request"), -AP_INIT_TAKE1("UseCanonicalName", set_use_canonical_name, NULL, - RSRC_CONF|ACCESS_CONF, - "How to work out the ServerName : Port when constructing URLs"), -/* TODO: RlimitFoo should all be part of mod_cgi, not in the core */ -/* TODO: ListenBacklog in MPM */ -AP_INIT_TAKE1("Include", include_config, NULL, - (RSRC_CONF | ACCESS_CONF | EXEC_ON_READ), - "Name of the config file to be included"), -AP_INIT_TAKE1("LogLevel", set_loglevel, NULL, RSRC_CONF, - "Level of verbosity in error logging"), -AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, - "A numeric IP address:port, or the name of a host"), -#ifdef _OSD_POSIX -AP_INIT_TAKE1("BS2000Account", set_bs2000_account, NULL, RSRC_CONF, - "Name of server User's bs2000 logon account name"), -#endif -AP_INIT_TAKE1("ServerTokens", set_serv_tokens, NULL, RSRC_CONF, - "Determine tokens displayed in the Server: header - Min(imal), OS or Full"), -AP_INIT_TAKE1("LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF, - "Limit on maximum size of an HTTP request line"), -AP_INIT_TAKE1("LimitRequestFieldsize", set_limit_req_fieldsize, NULL, - RSRC_CONF, - "Limit on maximum size of an HTTP request header field"), -AP_INIT_TAKE1("LimitRequestFields", set_limit_req_fields, NULL, RSRC_CONF, - "Limit (0 = unlimited) on max number of header fields in a request message"), -AP_INIT_TAKE1("LimitRequestBody", set_limit_req_body, - (void*)APR_OFFSETOF(core_dir_config, limit_req_body), OR_ALL, - "Limit (in bytes) on maximum size of request message body"), -AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL, - "Limit (in bytes) on maximum size of an XML-based request " - "body"), - -/* System Resource Controls */ -#ifdef RLIMIT_CPU -AP_INIT_TAKE12("RLimitCPU", set_limit_cpu, - (void*)APR_OFFSETOF(core_dir_config, limit_cpu), - OR_ALL, "Soft/hard limits for max CPU usage in seconds"), -#else -AP_INIT_TAKE12("RLimitCPU", no_set_limit, NULL, - OR_ALL, "Soft/hard limits for max CPU usage in seconds"), -#endif -#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined (RLIMIT_AS) -AP_INIT_TAKE12("RLimitMEM", set_limit_mem, - (void*)APR_OFFSETOF(core_dir_config, limit_mem), - OR_ALL, "Soft/hard limits for max memory usage per process"), -#else -AP_INIT_TAKE12("RLimitMEM", no_set_limit, NULL, - OR_ALL, "Soft/hard limits for max memory usage per process"), -#endif -#ifdef RLIMIT_NPROC -AP_INIT_TAKE12("RLimitNPROC", set_limit_nproc, - (void*)APR_OFFSETOF(core_dir_config, limit_nproc), - OR_ALL, "soft/hard limits for max number of processes per uid"), -#else -AP_INIT_TAKE12("RLimitNPROC", no_set_limit, NULL, - OR_ALL, "soft/hard limits for max number of processes per uid"), -#endif - -/* internal recursion stopper */ -AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF, - "maximum recursion depth of internal redirects and subrequests"), - -AP_INIT_TAKE1("ForceType", ap_set_string_slot_lower, - (void *)APR_OFFSETOF(core_dir_config, mime_type), OR_FILEINFO, - "a mime type that overrides other configured type"), -AP_INIT_TAKE1("SetHandler", ap_set_string_slot_lower, - (void *)APR_OFFSETOF(core_dir_config, handler), OR_FILEINFO, - "a handler name that overrides any other configured handler"), -AP_INIT_TAKE1("SetOutputFilter", ap_set_string_slot, - (void *)APR_OFFSETOF(core_dir_config, output_filters), OR_FILEINFO, - "filter (or ; delimited list of filters) to be run on the request content"), -AP_INIT_TAKE1("SetInputFilter", ap_set_string_slot, - (void *)APR_OFFSETOF(core_dir_config, input_filters), OR_FILEINFO, - "filter (or ; delimited list of filters) to be run on the request body"), -AP_INIT_ITERATE2("AddOutputFilterByType", add_ct_output_filters, - (void *)APR_OFFSETOF(core_dir_config, ct_output_filters), OR_FILEINFO, - "output filter name followed by one or more content-types"), -AP_INIT_FLAG("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, - "Allow URLs containing '/' encoded as '%2F'"), - -/* - * These are default configuration directives that mpms can/should - * pay attention to. If an mpm wishes to use these, they should - * #defined them in mpm.h. - */ -#ifdef AP_MPM_WANT_SET_PIDFILE -AP_INIT_TAKE1("PidFile", ap_mpm_set_pidfile, NULL, RSRC_CONF, - "A file for logging the server process ID"), -#endif -#ifdef AP_MPM_WANT_SET_SCOREBOARD -AP_INIT_TAKE1("ScoreBoardFile", ap_mpm_set_scoreboard, NULL, RSRC_CONF, - "A file for Apache to maintain runtime process management information"), -#endif -#ifdef AP_MPM_WANT_SET_LOCKFILE -AP_INIT_TAKE1("LockFile", ap_mpm_set_lockfile, NULL, RSRC_CONF, - "The lockfile used when Apache needs to lock the accept() call"), -#endif -#ifdef AP_MPM_WANT_SET_MAX_REQUESTS -AP_INIT_TAKE1("MaxRequestsPerChild", ap_mpm_set_max_requests, NULL, RSRC_CONF, - "Maximum number of requests a particular child serves before dying."), -#endif -#ifdef AP_MPM_WANT_SET_COREDUMPDIR -AP_INIT_TAKE1("CoreDumpDirectory", ap_mpm_set_coredumpdir, NULL, RSRC_CONF, - "The location of the directory Apache changes to before dumping core"), -#endif -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -AP_INIT_TAKE1("AcceptMutex", ap_mpm_set_accept_lock_mech, NULL, RSRC_CONF, - ap_valid_accept_mutex_string), -#endif -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE -AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF, - "Maximum number of 1k blocks a particular childs allocator may hold."), -#endif -#if AP_ENABLE_EXCEPTION_HOOK -AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF, - "Controls whether exception hook may be called after a crash"), -#endif -AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF, - "'on' (default), 'off' or 'extended' to trace request body content"), -{ NULL } -}; - -/***************************************************************** - * - * Core handlers for various phases of server operation... - */ - -AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r) -{ - void *sconf = r->server->module_config; - core_server_config *conf = ap_get_module_config(sconf, &core_module); - - /* XXX this seems too specific, this should probably become - * some general-case test - */ - if (r->proxyreq) { - return HTTP_FORBIDDEN; - } - if (!r->uri || ((r->uri[0] != '/') && strcmp(r->uri, "*"))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Invalid URI in request %s", r->the_request); - return HTTP_BAD_REQUEST; - } - - if (r->server->path - && !strncmp(r->uri, r->server->path, r->server->pathlen) - && (r->server->path[r->server->pathlen - 1] == '/' - || r->uri[r->server->pathlen] == '/' - || r->uri[r->server->pathlen] == '\0')) - { - /* skip all leading /'s (e.g. http://localhost///foo) - * so we are looking at only the relative path. - */ - char *path = r->uri + r->server->pathlen; - while (*path == '/') { - ++path; - } - if (apr_filepath_merge(&r->filename, conf->ap_document_root, path, - APR_FILEPATH_TRUENAME - | APR_FILEPATH_SECUREROOT, r->pool) - != APR_SUCCESS) { - return HTTP_FORBIDDEN; - } - r->canonical_filename = r->filename; - } - else { - /* - * Make sure that we do not mess up the translation by adding two - * /'s in a row. This happens under windows when the document - * root ends with a / - */ - /* skip all leading /'s (e.g. http://localhost///foo) - * so we are looking at only the relative path. - */ - char *path = r->uri; - while (*path == '/') { - ++path; - } - if (apr_filepath_merge(&r->filename, conf->ap_document_root, path, - APR_FILEPATH_TRUENAME - | APR_FILEPATH_SECUREROOT, r->pool) - != APR_SUCCESS) { - return HTTP_FORBIDDEN; - } - r->canonical_filename = r->filename; - } - - return OK; -} - -/***************************************************************** - * - * Test the filesystem name through directory_walk and file_walk - */ -static int core_map_to_storage(request_rec *r) -{ - int access_status; - - if ((access_status = ap_directory_walk(r))) { - return access_status; - } - - if ((access_status = ap_file_walk(r))) { - return access_status; - } - - return OK; -} - - -static int do_nothing(request_rec *r) { return OK; } - - -static int core_override_type(request_rec *r) -{ - core_dir_config *conf = - (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - /* Check for overrides with ForceType / SetHandler - */ - if (conf->mime_type && strcmp(conf->mime_type, "none")) - ap_set_content_type(r, (char*) conf->mime_type); - - if (conf->handler && strcmp(conf->handler, "none")) - r->handler = conf->handler; - - /* Deal with the poor soul who is trying to force path_info to be - * accepted within the core_handler, where they will let the subreq - * address its contents. This is toggled by the user in the very - * beginning of the fixup phase, so modules should override the user's - * discretion in their own module fixup phase. It is tristate, if - * the user doesn't specify, the result is 2 (which the module may - * interpret to its own customary behavior.) It won't be touched - * if the value is no longer undefined (2), so any module changing - * the value prior to the fixup phase OVERRIDES the user's choice. - */ - if ((r->used_path_info == AP_REQ_DEFAULT_PATH_INFO) - && (conf->accept_path_info != 3)) { - r->used_path_info = conf->accept_path_info; - } - - return OK; -} - - - -static int default_handler(request_rec *r) -{ - conn_rec *c = r->connection; - apr_bucket_brigade *bb; - apr_bucket *e; - core_dir_config *d; - int errstatus; - apr_file_t *fd = NULL; - apr_status_t status; - /* XXX if/when somebody writes a content-md5 filter we either need to - * remove this support or coordinate when to use the filter vs. - * when to use this code - * The current choice of when to compute the md5 here matches the 1.3 - * support fairly closely (unlike 1.3, we don't handle computing md5 - * when the charset is translated). - */ - int bld_content_md5; - - d = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - bld_content_md5 = (d->content_md5 & 1) - && r->output_filters->frec->ftype != AP_FTYPE_RESOURCE; - - ap_allow_standard_methods(r, MERGE_ALLOW, M_GET, M_OPTIONS, M_POST, -1); - - /* If filters intend to consume the request body, they must - * register an InputFilter to slurp the contents of the POST - * data from the POST input stream. It no longer exists when - * the output filters are invoked by the default handler. - */ - if ((errstatus = ap_discard_request_body(r)) != OK) { - return errstatus; - } - - if (r->method_number == M_GET || r->method_number == M_POST) { - if (r->finfo.filetype == 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "File does not exist: %s", r->filename); - return HTTP_NOT_FOUND; - } - - /* Don't try to serve a dir. Some OSs do weird things with - * raw I/O on a dir. - */ - if (r->finfo.filetype == APR_DIR) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Attempt to serve directory: %s", r->filename); - return HTTP_NOT_FOUND; - } - - if ((r->used_path_info != AP_REQ_ACCEPT_PATH_INFO) && - r->path_info && *r->path_info) - { - /* default to reject */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "File does not exist: %s", - apr_pstrcat(r->pool, r->filename, r->path_info, NULL)); - return HTTP_NOT_FOUND; - } - - /* We understood the (non-GET) method, but it might not be legal for - this particular resource. Check to see if the 'deliver_script' - flag is set. If so, then we go ahead and deliver the file since - it isn't really content (only GET normally returns content). - - Note: based on logic further above, the only possible non-GET - method at this point is POST. In the future, we should enable - script delivery for all methods. */ - if (r->method_number != M_GET) { - core_request_config *req_cfg; - - req_cfg = ap_get_module_config(r->request_config, &core_module); - if (!req_cfg->deliver_script) { - /* The flag hasn't been set for this request. Punt. */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "This resource does not accept the %s method.", - r->method); - return HTTP_METHOD_NOT_ALLOWED; - } - } - - - if ((status = apr_file_open(&fd, r->filename, APR_READ | APR_BINARY -#if APR_HAS_SENDFILE - | ((d->enable_sendfile == ENABLE_SENDFILE_OFF) - ? 0 : APR_SENDFILE_ENABLED) -#endif - , 0, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, - "file permissions deny server access: %s", r->filename); - return HTTP_FORBIDDEN; - } - - ap_update_mtime(r, r->finfo.mtime); - ap_set_last_modified(r); - ap_set_etag(r); - apr_table_setn(r->headers_out, "Accept-Ranges", "bytes"); - ap_set_content_length(r, r->finfo.size); - if ((errstatus = ap_meets_conditions(r)) != OK) { - apr_file_close(fd); - return errstatus; - } - - if (bld_content_md5) { - apr_table_setn(r->headers_out, "Content-MD5", - ap_md5digest(r->pool, fd)); - } - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - - /* For platforms where the size of the file may be larger than - * that which can be stored in a single bucket (whether the - * length field is an apr_size_t), split it into several - * buckets */ - if (sizeof(apr_off_t) > sizeof(apr_size_t) - && r->finfo.size > AP_MAX_SENDFILE) { - apr_off_t fsize = r->finfo.size; - e = apr_bucket_file_create(fd, 0, AP_MAX_SENDFILE, r->pool, - c->bucket_alloc); - while (fsize > AP_MAX_SENDFILE) { - apr_bucket *ce; - apr_bucket_copy(e, &ce); - APR_BRIGADE_INSERT_TAIL(bb, ce); - e->start += AP_MAX_SENDFILE; - fsize -= AP_MAX_SENDFILE; - } - e->length = (apr_size_t)fsize; /* Resize just the last bucket */ - } - else - e = apr_bucket_file_create(fd, 0, (apr_size_t)r->finfo.size, - r->pool, c->bucket_alloc); - -#if APR_HAS_MMAP - if (d->enable_mmap == ENABLE_MMAP_OFF) { - (void)apr_bucket_file_enable_mmap(e, 0); - } -#endif - APR_BRIGADE_INSERT_TAIL(bb, e); - e = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - - status = ap_pass_brigade(r->output_filters, bb); - if (status == APR_SUCCESS - || r->status != HTTP_OK - || c->aborted) { - return OK; /* r->status will be respected */ - } - else { - /* no way to know what type of error occurred */ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, - "default_handler: ap_pass_brigade returned %i", - status); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - else { /* unusual method (not GET or POST) */ - if (r->method_number == M_INVALID) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Invalid method in request %s", r->the_request); - return HTTP_NOT_IMPLEMENTED; - } - - if (r->method_number == M_OPTIONS) { - return ap_send_http_options(r); - } - return HTTP_METHOD_NOT_ALLOWED; - } -} - -typedef struct net_time_filter_ctx { - apr_socket_t *csd; - int first_line; -} net_time_filter_ctx_t; -static int net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, - ap_input_mode_t mode, apr_read_type_e block, - apr_off_t readbytes) -{ - net_time_filter_ctx_t *ctx = f->ctx; - int keptalive = f->c->keepalive == AP_CONN_KEEPALIVE; - - if (!ctx) { - f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx)); - ctx->first_line = 1; - ctx->csd = ap_get_module_config(f->c->conn_config, &core_module); - } - - if (mode != AP_MODE_INIT && mode != AP_MODE_EATCRLF) { - if (keptalive && ctx->first_line) { - apr_socket_timeout_set(ctx->csd, - f->c->base_server->keep_alive_timeout); - ctx->first_line = 0; - } - else { - if (keptalive) { - apr_socket_timeout_set(ctx->csd, f->c->base_server->timeout); - } - } - } - return ap_get_brigade(f->next, b, mode, block, readbytes); -} - -/** - * Remove all zero length buckets from the brigade. - */ -#define BRIGADE_NORMALIZE(b) \ -do { \ - apr_bucket *e = APR_BRIGADE_FIRST(b); \ - do { \ - if (e->length == 0 && !APR_BUCKET_IS_METADATA(e)) { \ - apr_bucket *d; \ - d = APR_BUCKET_NEXT(e); \ - apr_bucket_delete(e); \ - e = d; \ - } \ - e = APR_BUCKET_NEXT(e); \ - } while (!APR_BRIGADE_EMPTY(b) && (e != APR_BRIGADE_SENTINEL(b))); \ -} while (0) - - -/** - * Split the contents of a brigade after bucket 'e' to an existing brigade - * - * XXXX: Should this function be added to APR-Util? - */ -static void brigade_move(apr_bucket_brigade *b, apr_bucket_brigade *a, - apr_bucket *e) -{ - apr_bucket *f; - - if (e != APR_BRIGADE_SENTINEL(b)) { - f = APR_RING_LAST(&b->list); - APR_RING_UNSPLICE(e, f, link); - APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link); - } - - APR_BRIGADE_CHECK_CONSISTENCY(a); - APR_BRIGADE_CHECK_CONSISTENCY(b); -} - - -static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, - ap_input_mode_t mode, apr_read_type_e block, - apr_off_t readbytes) -{ - apr_bucket *e; - apr_status_t rv; - core_net_rec *net = f->ctx; - core_ctx_t *ctx = net->in_ctx; - const char *str; - apr_size_t len; - - if (mode == AP_MODE_INIT) { - /* - * this mode is for filters that might need to 'initialize' - * a connection before reading request data from a client. - * NNTP over SSL for example needs to handshake before the - * server sends the welcome message. - * such filters would have changed the mode before this point - * is reached. however, protocol modules such as NNTP should - * not need to know anything about SSL. given the example, if - * SSL is not in the filter chain, AP_MODE_INIT is a noop. - */ - return APR_SUCCESS; - } - - if (!ctx) - { - ctx = apr_pcalloc(f->c->pool, sizeof(*ctx)); - ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc); - ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc); - - /* seed the brigade with the client socket. */ - e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(ctx->b, e); - net->in_ctx = ctx; - } - else if (APR_BRIGADE_EMPTY(ctx->b)) { - return APR_EOF; - } - - /* ### This is bad. */ - BRIGADE_NORMALIZE(ctx->b); - - /* check for empty brigade again *AFTER* BRIGADE_NORMALIZE() - * If we have lost our socket bucket (see above), we are EOF. - * - * Ideally, this should be returning SUCCESS with EOS bucket, but - * some higher-up APIs (spec. read_request_line via ap_rgetline) - * want an error code. */ - if (APR_BRIGADE_EMPTY(ctx->b)) { - return APR_EOF; - } - - if (mode == AP_MODE_GETLINE) { - /* we are reading a single LF line, e.g. the HTTP headers */ - rv = apr_brigade_split_line(b, ctx->b, block, HUGE_STRING_LEN); - /* We should treat EAGAIN here the same as we do for EOF (brigade is - * empty). We do this by returning whatever we have read. This may - * or may not be bogus, but is consistent (for now) with EOF logic. - */ - if (APR_STATUS_IS_EAGAIN(rv)) { - rv = APR_SUCCESS; - } - return rv; - } - - /* ### AP_MODE_PEEK is a horrific name for this mode because we also - * eat any CRLFs that we see. That's not the obvious intention of - * this mode. Determine whether anyone actually uses this or not. */ - if (mode == AP_MODE_EATCRLF) { - apr_bucket *e; - const char *c; - - /* The purpose of this loop is to ignore any CRLF (or LF) at the end - * of a request. Many browsers send extra lines at the end of POST - * requests. We use the PEEK method to determine if there is more - * data on the socket, so that we know if we should delay sending the - * end of one request until we have served the second request in a - * pipelined situation. We don't want to actually delay sending a - * response if the server finds a CRLF (or LF), becuause that doesn't - * mean that there is another request, just a blank line. - */ - while (1) { - if (APR_BRIGADE_EMPTY(ctx->b)) - return APR_EOF; - - e = APR_BRIGADE_FIRST(ctx->b); - - rv = apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ); - - if (rv != APR_SUCCESS) - return rv; - - c = str; - while (c < str + len) { - if (*c == APR_ASCII_LF) - c++; - else if (*c == APR_ASCII_CR && *(c + 1) == APR_ASCII_LF) - c += 2; - else - return APR_SUCCESS; - } - - /* If we reach here, we were a bucket just full of CRLFs, so - * just toss the bucket. */ - /* FIXME: Is this the right thing to do in the core? */ - apr_bucket_delete(e); - } - return APR_SUCCESS; - } - - /* If mode is EXHAUSTIVE, we want to just read everything until the end - * of the brigade, which in this case means the end of the socket. - * To do this, we attach the brigade that has currently been setaside to - * the brigade that was passed down, and send that brigade back. - * - * NOTE: This is VERY dangerous to use, and should only be done with - * extreme caution. However, the Perchild MPM needs this feature - * if it is ever going to work correctly again. With this, the Perchild - * MPM can easily request the socket and all data that has been read, - * which means that it can pass it to the correct child process. - */ - if (mode == AP_MODE_EXHAUSTIVE) { - apr_bucket *e; - - /* Tack on any buckets that were set aside. */ - APR_BRIGADE_CONCAT(b, ctx->b); - - /* Since we've just added all potential buckets (which will most - * likely simply be the socket bucket) we know this is the end, - * so tack on an EOS too. */ - /* We have read until the brigade was empty, so we know that we - * must be EOS. */ - e = apr_bucket_eos_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(b, e); - return APR_SUCCESS; - } - - /* read up to the amount they specified. */ - if (mode == AP_MODE_READBYTES || mode == AP_MODE_SPECULATIVE) { - apr_bucket *e; - - AP_DEBUG_ASSERT(readbytes > 0); - - e = APR_BRIGADE_FIRST(ctx->b); - rv = apr_bucket_read(e, &str, &len, block); - - if (APR_STATUS_IS_EAGAIN(rv)) { - return APR_SUCCESS; - } - else if (rv != APR_SUCCESS) { - return rv; - } - else if (block == APR_BLOCK_READ && len == 0) { - /* We wanted to read some bytes in blocking mode. We read - * 0 bytes. Hence, we now assume we are EOS. - * - * When we are in normal mode, return an EOS bucket to the - * caller. - * When we are in speculative mode, leave ctx->b empty, so - * that the next call returns an EOS bucket. - */ - apr_bucket_delete(e); - - if (mode == AP_MODE_READBYTES) { - e = apr_bucket_eos_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(b, e); - } - return APR_SUCCESS; - } - - /* We can only return at most what we read. */ - if (len < readbytes) { - readbytes = len; - } - - rv = apr_brigade_partition(ctx->b, readbytes, &e); - if (rv != APR_SUCCESS) { - return rv; - } - - /* Must do move before CONCAT */ - brigade_move(ctx->b, ctx->tmpbb, e); - - if (mode == AP_MODE_READBYTES) { - APR_BRIGADE_CONCAT(b, ctx->b); - } - else if (mode == AP_MODE_SPECULATIVE) { - apr_bucket *copy_bucket; - APR_BRIGADE_FOREACH(e, ctx->b) { - rv = apr_bucket_copy(e, ©_bucket); - if (rv != APR_SUCCESS) { - return rv; - } - APR_BRIGADE_INSERT_TAIL(b, copy_bucket); - } - } - - /* Take what was originally there and place it back on ctx->b */ - APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb); - } - return APR_SUCCESS; -} - -/* Default filter. This filter should almost always be used. Its only job - * is to send the headers if they haven't already been sent, and then send - * the actual data. - */ -#define MAX_IOVEC_TO_WRITE 16 - -/* Optional function coming from mod_logio, used for logging of output - * traffic - */ -static APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *logio_add_bytes_out; - -static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) -{ - apr_status_t rv; - apr_bucket_brigade *more; - conn_rec *c = f->c; - core_net_rec *net = f->ctx; - core_output_filter_ctx_t *ctx = net->out_ctx; - apr_read_type_e eblock = APR_NONBLOCK_READ; - apr_pool_t *input_pool = b->p; - - /* Fail quickly if the connection has already been aborted. */ - if (c->aborted) { - apr_brigade_cleanup(b); - return APR_ECONNABORTED; - } - - if (ctx == NULL) { - ctx = apr_pcalloc(c->pool, sizeof(*ctx)); - net->out_ctx = ctx; - } - - /* If we have a saved brigade, concatenate the new brigade to it */ - if (ctx->b) { - APR_BRIGADE_CONCAT(ctx->b, b); - b = ctx->b; - ctx->b = NULL; - } - - /* Perform multiple passes over the brigade, sending batches of output - to the connection. */ - while (b && !APR_BRIGADE_EMPTY(b)) { - apr_size_t nbytes = 0; - apr_bucket *last_e = NULL; /* initialized for debugging */ - apr_bucket *e; - - /* one group of iovecs per pass over the brigade */ - apr_size_t nvec = 0; - apr_size_t nvec_trailers = 0; - struct iovec vec[MAX_IOVEC_TO_WRITE]; - struct iovec vec_trailers[MAX_IOVEC_TO_WRITE]; - - /* one file per pass over the brigade */ - apr_file_t *fd = NULL; - apr_size_t flen = 0; - apr_off_t foffset = 0; - - /* keep track of buckets that we've concatenated - * to avoid small writes - */ - apr_bucket *last_merged_bucket = NULL; - - /* tail of brigade if we need another pass */ - more = NULL; - - /* Iterate over the brigade: collect iovecs and/or a file */ - APR_BRIGADE_FOREACH(e, b) { - /* keep track of the last bucket processed */ - last_e = e; - if (APR_BUCKET_IS_EOS(e) || AP_BUCKET_IS_EOC(e)) { - break; - } - else if (APR_BUCKET_IS_FLUSH(e)) { - if (e != APR_BRIGADE_LAST(b)) { - more = apr_brigade_split(b, APR_BUCKET_NEXT(e)); - } - break; - } - - /* It doesn't make any sense to use sendfile for a file bucket - * that represents 10 bytes. - */ - else if (APR_BUCKET_IS_FILE(e) - && (e->length >= AP_MIN_SENDFILE_BYTES)) { - apr_bucket_file *a = e->data; - - /* We can't handle more than one file bucket at a time - * so we split here and send the file we have already - * found. - */ - if (fd) { - more = apr_brigade_split(b, e); - break; - } - - fd = a->fd; - flen = e->length; - foffset = e->start; - } - else { - const char *str; - apr_size_t n; - - rv = apr_bucket_read(e, &str, &n, eblock); - if (APR_STATUS_IS_EAGAIN(rv)) { - /* send what we have so far since we shouldn't expect more - * output for a while... next time we read, block - */ - more = apr_brigade_split(b, e); - eblock = APR_BLOCK_READ; - break; - } - eblock = APR_NONBLOCK_READ; - if (n) { - if (!fd) { - if (nvec == MAX_IOVEC_TO_WRITE) { - /* woah! too many. buffer them up, for use later. */ - apr_bucket *temp, *next; - apr_bucket_brigade *temp_brig; - - if (nbytes >= AP_MIN_BYTES_TO_WRITE) { - /* We have enough data in the iovec - * to justify doing a writev - */ - more = apr_brigade_split(b, e); - break; - } - - /* Create a temporary brigade as a means - * of concatenating a bunch of buckets together - */ - if (last_merged_bucket) { - /* If we've concatenated together small - * buckets already in a previous pass, - * the initial buckets in this brigade - * are heap buckets that may have extra - * space left in them (because they - * were created by apr_brigade_write()). - * We can take advantage of this by - * building the new temp brigade out of - * these buckets, so that the content - * in them doesn't have to be copied again. - */ - apr_bucket_brigade *bb; - bb = apr_brigade_split(b, - APR_BUCKET_NEXT(last_merged_bucket)); - temp_brig = b; - b = bb; - } - else { - temp_brig = apr_brigade_create(f->c->pool, - f->c->bucket_alloc); - } - - temp = APR_BRIGADE_FIRST(b); - while (temp != e) { - apr_bucket *d; - rv = apr_bucket_read(temp, &str, &n, APR_BLOCK_READ); - apr_brigade_write(temp_brig, NULL, NULL, str, n); - d = temp; - temp = APR_BUCKET_NEXT(temp); - apr_bucket_delete(d); - } - - nvec = 0; - nbytes = 0; - temp = APR_BRIGADE_FIRST(temp_brig); - APR_BUCKET_REMOVE(temp); - APR_BRIGADE_INSERT_HEAD(b, temp); - apr_bucket_read(temp, &str, &n, APR_BLOCK_READ); - vec[nvec].iov_base = (char*) str; - vec[nvec].iov_len = n; - nvec++; - - /* Just in case the temporary brigade has - * multiple buckets, recover the rest of - * them and put them in the brigade that - * we're sending. - */ - for (next = APR_BRIGADE_FIRST(temp_brig); - next != APR_BRIGADE_SENTINEL(temp_brig); - next = APR_BRIGADE_FIRST(temp_brig)) { - APR_BUCKET_REMOVE(next); - APR_BUCKET_INSERT_AFTER(temp, next); - temp = next; - apr_bucket_read(next, &str, &n, - APR_BLOCK_READ); - vec[nvec].iov_base = (char*) str; - vec[nvec].iov_len = n; - nvec++; - } - - apr_brigade_destroy(temp_brig); - - last_merged_bucket = temp; - e = temp; - last_e = e; - } - else { - vec[nvec].iov_base = (char*) str; - vec[nvec].iov_len = n; - nvec++; - } - } - else { - /* The bucket is a trailer to a file bucket */ - - if (nvec_trailers == MAX_IOVEC_TO_WRITE) { - /* woah! too many. stop now. */ - more = apr_brigade_split(b, e); - break; - } - - vec_trailers[nvec_trailers].iov_base = (char*) str; - vec_trailers[nvec_trailers].iov_len = n; - nvec_trailers++; - } - - nbytes += n; - } - } - } - - - /* Completed iterating over the brigade, now determine if we want - * to buffer the brigade or send the brigade out on the network. - * - * Save if we haven't accumulated enough bytes to send, the connection - * is not about to be closed, and: - * - * 1) we didn't see a file, we don't have more passes over the - * brigade to perform, AND we didn't stop at a FLUSH bucket. - * (IOW, we will save plain old bytes such as HTTP headers) - * or - * 2) we hit the EOS and have a keep-alive connection - * (IOW, this response is a bit more complex, but we save it - * with the hope of concatenating with another response) - */ - if (nbytes + flen < AP_MIN_BYTES_TO_WRITE - && !AP_BUCKET_IS_EOC(last_e) - && ((!fd && !more && !APR_BUCKET_IS_FLUSH(last_e)) - || (APR_BUCKET_IS_EOS(last_e) - && c->keepalive == AP_CONN_KEEPALIVE))) { - - /* NEVER save an EOS in here. If we are saving a brigade with - * an EOS bucket, then we are doing keepalive connections, and - * we want to process to second request fully. - */ - if (APR_BUCKET_IS_EOS(last_e)) { - apr_bucket *bucket; - int file_bucket_saved = 0; - apr_bucket_delete(last_e); - for (bucket = APR_BRIGADE_FIRST(b); - bucket != APR_BRIGADE_SENTINEL(b); - bucket = APR_BUCKET_NEXT(bucket)) { - - /* Do a read on each bucket to pull in the - * data from pipe and socket buckets, so - * that we don't leave their file descriptors - * open indefinitely. Do the same for file - * buckets, with one exception: allow the - * first file bucket in the brigade to remain - * a file bucket, so that we don't end up - * doing an mmap+memcpy every time a client - * requests a <8KB file over a keepalive - * connection. - */ - if (APR_BUCKET_IS_FILE(bucket) && !file_bucket_saved) { - file_bucket_saved = 1; - } - else { - const char *buf; - apr_size_t len = 0; - rv = apr_bucket_read(bucket, &buf, &len, - APR_BLOCK_READ); - if (rv != APR_SUCCESS) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, - c, "core_output_filter:" - " Error reading from bucket."); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - } - } - if (!ctx->deferred_write_pool) { - apr_pool_create(&ctx->deferred_write_pool, c->pool); - apr_pool_tag(ctx->deferred_write_pool, "deferred_write"); - } - ap_save_brigade(f, &ctx->b, &b, ctx->deferred_write_pool); - - return APR_SUCCESS; - } - - if (fd) { - apr_hdtr_t hdtr; - apr_size_t bytes_sent; - -#if APR_HAS_SENDFILE - apr_int32_t flags = 0; -#endif - - memset(&hdtr, '\0', sizeof(hdtr)); - if (nvec) { - hdtr.numheaders = nvec; - hdtr.headers = vec; - } - - if (nvec_trailers) { - hdtr.numtrailers = nvec_trailers; - hdtr.trailers = vec_trailers; - } - -#if APR_HAS_SENDFILE - if (apr_file_flags_get(fd) & APR_SENDFILE_ENABLED) { - - if (c->keepalive == AP_CONN_CLOSE && APR_BUCKET_IS_EOS(last_e)) { - /* Prepare the socket to be reused */ - flags |= APR_SENDFILE_DISCONNECT_SOCKET; - } - - rv = sendfile_it_all(net, /* the network information */ - fd, /* the file to send */ - &hdtr, /* header and trailer iovecs */ - foffset, /* offset in the file to begin - sending from */ - flen, /* length of file */ - nbytes + flen, /* total length including - headers */ - &bytes_sent, /* how many bytes were - sent */ - flags); /* apr_sendfile flags */ - - if (logio_add_bytes_out && bytes_sent > 0) - logio_add_bytes_out(c, bytes_sent); - } - else -#endif - { - rv = emulate_sendfile(net, fd, &hdtr, foffset, flen, - &bytes_sent); - - if (logio_add_bytes_out && bytes_sent > 0) - logio_add_bytes_out(c, bytes_sent); - } - - fd = NULL; - } - else { - apr_size_t bytes_sent; - - rv = writev_it_all(net->client_socket, - vec, nvec, - nbytes, &bytes_sent); - - if (logio_add_bytes_out && bytes_sent > 0) - logio_add_bytes_out(c, bytes_sent); - } - - apr_brigade_destroy(b); - - /* drive cleanups for resources which were set aside - * this may occur before or after termination of the request which - * created the resource - */ - if (ctx->deferred_write_pool) { - if (more && more->p == ctx->deferred_write_pool) { - /* "more" belongs to the deferred_write_pool, - * which is about to be cleared. - */ - if (APR_BRIGADE_EMPTY(more)) { - more = NULL; - } - else { - /* uh oh... change more's lifetime - * to the input brigade's lifetime - */ - apr_bucket_brigade *tmp_more = more; - more = NULL; - ap_save_brigade(f, &more, &tmp_more, input_pool); - } - } - apr_pool_clear(ctx->deferred_write_pool); - } - - if (rv != APR_SUCCESS) { - ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, - "core_output_filter: writing data to the network"); - - if (more) - apr_brigade_destroy(more); - - /* No need to check for SUCCESS, we did that above. */ - if (!APR_STATUS_IS_EAGAIN(rv)) { - c->aborted = 1; - return APR_ECONNABORTED; - } - - return APR_SUCCESS; - } - - b = more; - more = NULL; - } /* end while () */ - - return APR_SUCCESS; -} - -static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out); - - ap_set_version(pconf); - ap_setup_make_content_type(pconf); - return OK; -} - -static void core_insert_filter(request_rec *r) -{ - core_dir_config *conf = (core_dir_config *) - ap_get_module_config(r->per_dir_config, - &core_module); - const char *filter, *filters = conf->output_filters; - - if (filters) { - while (*filters && (filter = ap_getword(r->pool, &filters, ';'))) { - ap_add_output_filter(filter, NULL, r, r->connection); - } - } - - filters = conf->input_filters; - if (filters) { - while (*filters && (filter = ap_getword(r->pool, &filters, ';'))) { - ap_add_input_filter(filter, NULL, r, r->connection); - } - } -} - -static apr_size_t num_request_notes = AP_NUM_STD_NOTES; - -static apr_status_t reset_request_notes(void *dummy) -{ - num_request_notes = AP_NUM_STD_NOTES; - return APR_SUCCESS; -} - -AP_DECLARE(apr_size_t) ap_register_request_note(void) -{ - apr_pool_cleanup_register(apr_hook_global_pool, NULL, reset_request_notes, - apr_pool_cleanup_null); - return num_request_notes++; -} - -AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num) -{ - core_request_config *req_cfg; - - if (note_num >= num_request_notes) { - return NULL; - } - - req_cfg = (core_request_config *) - ap_get_module_config(r->request_config, &core_module); - - if (!req_cfg) { - return NULL; - } - - return &(req_cfg->notes[note_num]); -} - -static int core_create_req(request_rec *r) -{ - /* Alloc the config struct and the array of request notes in - * a single block for efficiency - */ - core_request_config *req_cfg; - - req_cfg = apr_pcalloc(r->pool, sizeof(core_request_config) + - sizeof(void *) * num_request_notes); - req_cfg->notes = (void **)((char *)req_cfg + sizeof(core_request_config)); - - /* ### temporarily enable script delivery as the default */ - req_cfg->deliver_script = 1; - - if (r->main) { - core_request_config *main_req_cfg = (core_request_config *) - ap_get_module_config(r->main->request_config, &core_module); - req_cfg->bb = main_req_cfg->bb; - } - else { - req_cfg->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - if (!r->prev) { - ap_add_input_filter_handle(ap_net_time_filter_handle, - NULL, r, r->connection); - } - } - - ap_set_module_config(r->request_config, &core_module, req_cfg); - - /* Begin by presuming any module can make its own path_info assumptions, - * until some module interjects and changes the value. - */ - r->used_path_info = AP_REQ_DEFAULT_PATH_INFO; - - return OK; -} - -static int core_create_proxy_req(request_rec *r, request_rec *pr) -{ - return core_create_req(pr); -} - -static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, - apr_socket_t *csd, long id, void *sbh, - apr_bucket_alloc_t *alloc) -{ - apr_status_t rv; - conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); - - c->sbh = sbh; - (void)ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *)NULL); - - /* Got a connection structure, so initialize what fields we can - * (the rest are zeroed out by pcalloc). - */ - c->conn_config = ap_create_conn_config(ptrans); - c->notes = apr_table_make(ptrans, 5); - - c->pool = ptrans; - if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, - "apr_socket_addr_get(APR_LOCAL)"); - apr_socket_close(csd); - return NULL; - } - - apr_sockaddr_ip_get(&c->local_ip, c->local_addr); - if ((rv = apr_socket_addr_get(&c->remote_addr, APR_REMOTE, csd)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, - "apr_socket_addr_get(APR_REMOTE)"); - apr_socket_close(csd); - return NULL; - } - - apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr); - c->base_server = server; - - c->id = id; - c->bucket_alloc = alloc; - - return c; -} - -static int core_pre_connection(conn_rec *c, void *csd) -{ - core_net_rec *net = apr_palloc(c->pool, sizeof(*net)); - apr_status_t rv; - -#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK - /* BillS says perhaps this should be moved to the MPMs. Some OSes - * allow listening socket attributes to be inherited by the - * accept sockets which means this call only needs to be made - * once on the listener - */ - /* The Nagle algorithm says that we should delay sending partial - * packets in hopes of getting more data. We don't want to do - * this; we are not telnet. There are bad interactions between - * persistent connections and Nagle's algorithm that have very severe - * performance penalties. (Failing to disable Nagle is not much of a - * problem with simple HTTP.) - */ - rv = apr_socket_opt_set(csd, APR_TCP_NODELAY, 1); - if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) { - /* expected cause is that the client disconnected already, - * hence the debug level - */ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, - "apr_socket_opt_set(APR_TCP_NODELAY)"); - } -#endif - - /* The core filter requires the timeout mode to be set, which - * incidentally sets the socket to be nonblocking. If this - * is not initialized correctly, Linux - for example - will - * be initially blocking, while Solaris will be non blocking - * and any initial read will fail. - */ - rv = apr_socket_timeout_set(csd, c->base_server->timeout); - if (rv != APR_SUCCESS) { - /* expected cause is that the client disconnected already */ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, - "apr_socket_timeout_set"); - } - - net->c = c; - net->in_ctx = NULL; - net->out_ctx = NULL; - net->client_socket = csd; - - ap_set_module_config(net->c->conn_config, &core_module, csd); - ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c); - ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c); - return DONE; -} - -static void register_hooks(apr_pool_t *p) -{ - /* create_connection and install_transport_filters are - * hooks that should always be APR_HOOK_REALLY_LAST to give other - * modules the opportunity to install alternate network transports - * and stop other functions from being run. - */ - ap_hook_create_connection(core_create_conn, NULL, NULL, - APR_HOOK_REALLY_LAST); - ap_hook_pre_connection(core_pre_connection, NULL, NULL, - APR_HOOK_REALLY_LAST); - - ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST); - ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST); - ap_hook_map_to_storage(core_map_to_storage,NULL,NULL,APR_HOOK_REALLY_LAST); - ap_hook_open_logs(ap_open_logs,NULL,NULL,APR_HOOK_REALLY_FIRST); - ap_hook_child_init(ap_logs_child_init,NULL,NULL,APR_HOOK_MIDDLE); - ap_hook_handler(default_handler,NULL,NULL,APR_HOOK_REALLY_LAST); - /* FIXME: I suspect we can eliminate the need for these do_nothings - Ben */ - ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST); - ap_hook_fixups(core_override_type,NULL,NULL,APR_HOOK_REALLY_FIRST); - ap_hook_access_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST); - ap_hook_create_request(core_create_req, NULL, NULL, APR_HOOK_MIDDLE); - APR_OPTIONAL_HOOK(proxy, create_req, core_create_proxy_req, NULL, NULL, - APR_HOOK_MIDDLE); - ap_hook_pre_mpm(ap_create_scoreboard, NULL, NULL, APR_HOOK_MIDDLE); - - /* register the core's insert_filter hook and register core-provided - * filters - */ - ap_hook_insert_filter(core_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); - - ap_core_input_filter_handle = - ap_register_input_filter("CORE_IN", core_input_filter, - NULL, AP_FTYPE_NETWORK); - ap_net_time_filter_handle = - ap_register_input_filter("NET_TIME", net_time_filter, - NULL, AP_FTYPE_PROTOCOL); - ap_content_length_filter_handle = - ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter, - NULL, AP_FTYPE_PROTOCOL); - ap_core_output_filter_handle = - ap_register_output_filter("CORE", core_output_filter, - NULL, AP_FTYPE_NETWORK); - ap_subreq_core_filter_handle = - ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter, - NULL, AP_FTYPE_CONTENT_SET); - ap_old_write_func = - ap_register_output_filter("OLD_WRITE", ap_old_write_filter, - NULL, AP_FTYPE_RESOURCE - 10); -} - -AP_DECLARE_DATA module core_module = { - STANDARD20_MODULE_STUFF, - create_core_dir_config, /* create per-directory config structure */ - merge_core_dir_configs, /* merge per-directory config structures */ - create_core_server_config, /* create per-server config structure */ - merge_core_server_configs, /* merge per-server config structures */ - core_cmds, /* command apr_table_t */ - register_hooks /* register hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/server/core.lo b/rubbos/app/httpd-2.0.64/server/core.lo deleted file mode 100644 index 0a5a94eb..00000000 --- a/rubbos/app/httpd-2.0.64/server/core.lo +++ /dev/null @@ -1,12 +0,0 @@ -# core.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/core.o' - -# Name of the non-PIC object. -non_pic_object='core.o' - diff --git a/rubbos/app/httpd-2.0.64/server/core.o b/rubbos/app/httpd-2.0.64/server/core.o Binary files differdeleted file mode 100644 index df7ffe55..00000000 --- a/rubbos/app/httpd-2.0.64/server/core.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/eoc_bucket.c b/rubbos/app/httpd-2.0.64/server/eoc_bucket.c deleted file mode 100644 index 0c6ce7a5..00000000 --- a/rubbos/app/httpd-2.0.64/server/eoc_bucket.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "httpd.h" -#include "http_connection.h" - -static apr_status_t eoc_bucket_read(apr_bucket *b, const char **str, - apr_size_t *len, apr_read_type_e block) -{ - *str = NULL; - *len = 0; - return APR_SUCCESS; -} - -AP_DECLARE(apr_bucket *) ap_bucket_eoc_make(apr_bucket *b) -{ - b->length = 0; - b->start = 0; - b->data = NULL; - b->type = &ap_bucket_type_eoc; - - return b; -} - -AP_DECLARE(apr_bucket *) ap_bucket_eoc_create(apr_bucket_alloc_t *list) -{ - apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); - - APR_BUCKET_INIT(b); - b->free = apr_bucket_free; - b->list = list; - return ap_bucket_eoc_make(b); -} - -AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_eoc = { - "EOC", 5, APR_BUCKET_METADATA, - apr_bucket_destroy_noop, - eoc_bucket_read, - apr_bucket_setaside_noop, - apr_bucket_split_notimpl, - apr_bucket_simple_copy -}; diff --git a/rubbos/app/httpd-2.0.64/server/eoc_bucket.lo b/rubbos/app/httpd-2.0.64/server/eoc_bucket.lo deleted file mode 100644 index 628d3cb7..00000000 --- a/rubbos/app/httpd-2.0.64/server/eoc_bucket.lo +++ /dev/null @@ -1,12 +0,0 @@ -# eoc_bucket.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/eoc_bucket.o' - -# Name of the non-PIC object. -non_pic_object='eoc_bucket.o' - diff --git a/rubbos/app/httpd-2.0.64/server/eoc_bucket.o b/rubbos/app/httpd-2.0.64/server/eoc_bucket.o Binary files differdeleted file mode 100644 index 9bdedb94..00000000 --- a/rubbos/app/httpd-2.0.64/server/eoc_bucket.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/error_bucket.c b/rubbos/app/httpd-2.0.64/server/error_bucket.c deleted file mode 100644 index d113c171..00000000 --- a/rubbos/app/httpd-2.0.64/server/error_bucket.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "http_protocol.h" -#include "apr_buckets.h" -#include "apr_strings.h" -#if APR_HAVE_STRINGS_H -#include <strings.h> -#endif - -static apr_status_t error_bucket_read(apr_bucket *b, const char **str, - apr_size_t *len, apr_read_type_e block) -{ - *str = NULL; - *len = 0; - return APR_SUCCESS; -} - -static void error_bucket_destroy(void *data) -{ - ap_bucket_error *h = data; - - if (apr_bucket_shared_destroy(h)) { - apr_bucket_free(h); - } -} - -AP_DECLARE(apr_bucket *) ap_bucket_error_make(apr_bucket *b, int error, - const char *buf, apr_pool_t *p) -{ - ap_bucket_error *h; - - h = apr_bucket_alloc(sizeof(*h), b->list); - h->status = error; - h->data = (buf) ? apr_pstrdup(p, buf) : NULL; - - b = apr_bucket_shared_make(b, h, 0, 0); - b->type = &ap_bucket_type_error; - return b; -} - -AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf, - apr_pool_t *p, - apr_bucket_alloc_t *list) -{ - apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); - - APR_BUCKET_INIT(b); - b->free = apr_bucket_free; - b->list = list; - return ap_bucket_error_make(b, error, buf, p); -} - -AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_error = { - "ERROR", 5, APR_BUCKET_METADATA, - error_bucket_destroy, - error_bucket_read, - apr_bucket_setaside_notimpl, - apr_bucket_split_notimpl, - apr_bucket_shared_copy -}; diff --git a/rubbos/app/httpd-2.0.64/server/error_bucket.lo b/rubbos/app/httpd-2.0.64/server/error_bucket.lo deleted file mode 100644 index f7649cae..00000000 --- a/rubbos/app/httpd-2.0.64/server/error_bucket.lo +++ /dev/null @@ -1,12 +0,0 @@ -# error_bucket.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/error_bucket.o' - -# Name of the non-PIC object. -non_pic_object='error_bucket.o' - diff --git a/rubbos/app/httpd-2.0.64/server/error_bucket.o b/rubbos/app/httpd-2.0.64/server/error_bucket.o Binary files differdeleted file mode 100644 index 03198e00..00000000 --- a/rubbos/app/httpd-2.0.64/server/error_bucket.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/export_files b/rubbos/app/httpd-2.0.64/server/export_files deleted file mode 100644 index f61331e5..00000000 --- a/rubbos/app/httpd-2.0.64/server/export_files +++ /dev/null @@ -1,97 +0,0 @@ -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_compat.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_config_auto.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_config.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_config_layout.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_listen.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_mmn.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_mpm.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_provider.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_regkey.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/ap_release.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_config.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_connection.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_core.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/httpd.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_log.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_main.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_protocol.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_request.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/http_vhost.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/mpm_common.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/pcreposix.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/rfc1413.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/scoreboard.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_cfgtree.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_charset.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_ebcdic.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_filter.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_ldap.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_md5.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_script.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_time.h -/bottlenecks/rubbos/app/httpd-2.0.64/include/util_xml.h -/bottlenecks/rubbos/app/httpd-2.0.64/modules/http/mod_core.h -/bottlenecks/rubbos/app/httpd-2.0.64/os/unix/os.h -/bottlenecks/rubbos/app/httpd-2.0.64/os/unix/unixd.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_allocator.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_atomic.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_compat.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_dso.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_env.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_errno.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_file_info.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_file_io.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_fnmatch.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_general.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_getopt.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_global_mutex.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_hash.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_inherit.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_lib.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_mmap.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_network_io.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_poll.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_pools.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_portable.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_proc_mutex.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_ring.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_shm.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_signal.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_strings.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_support.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_tables.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_cond.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_mutex.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_proc.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_rwlock.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_time.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_user.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_version.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_want.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_anylock.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_base64.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_buckets.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_date.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_dbm.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_hooks.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_ldap.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_ldap_url.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_md4.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_md5.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_optional.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_optional_hooks.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_queue.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_reslist.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_rmm.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_sdbm.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_sha1.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_strmatch.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_uri.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_uuid.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_xlate.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_xml.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apu_compat.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apu.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apu_version.h -/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apu_want.h diff --git a/rubbos/app/httpd-2.0.64/server/export_vars.h b/rubbos/app/httpd-2.0.64/server/export_vars.h deleted file mode 100644 index daa98faa..00000000 --- a/rubbos/app/httpd-2.0.64/server/export_vars.h +++ /dev/null @@ -1,51 +0,0 @@ -ap_listeners -ap_top_module -ap_prelinked_modules -ap_preloaded_modules -ap_loaded_modules -ap_bucket_type_eoc -core_module -ap_subreq_core_filter_handle -ap_core_output_filter_handle -ap_content_length_filter_handle -ap_net_time_filter_handle -ap_core_input_filter_handle -ap_server_argv0 -ap_server_root -ap_server_pre_read_config -ap_server_post_read_config -ap_server_config_defines -ap_old_write_func -ap_bucket_type_error -ap_scoreboard_image -ap_scoreboard_fname -ap_extended_status -ap_my_generation -ap_conftree -ap_http_input_filter_handle -ap_http_header_filter_handle -ap_chunk_filter_handle -ap_byterange_filter_handle -unixd_config -apr_month_snames -apr_day_snames -apr_bucket_type_flush -apr_bucket_type_eos -apr_bucket_type_file -apr_bucket_type_heap -#ifdef APR_HAS_MMAP - apr_bucket_type_mmap -#endif /* APR_HAS_MMAP */ -apr_bucket_type_pool -apr_bucket_type_pipe -apr_bucket_type_immortal -apr_bucket_type_transient -apr_bucket_type_socket -#ifdef APR_HAS_MMAP -#endif /* APR_HAS_MMAP */ -apr_hook_global_pool -apr_global_hook_pool -apr_hook_debug_enabled -apr_debug_module_hooks -apr_hook_debug_current -apr_current_hooking_module diff --git a/rubbos/app/httpd-2.0.64/server/exports.c b/rubbos/app/httpd-2.0.64/server/exports.c deleted file mode 100644 index 806a8756..00000000 --- a/rubbos/app/httpd-2.0.64/server/exports.c +++ /dev/null @@ -1,1520 +0,0 @@ -/* - * THIS FILE WAS AUTOGENERATED BY make_exports.awk - * - * This is an ugly hack that needs to be here, so - * that libtool will link all of the APR functions - * into server regardless of whether the base server - * uses them. - */ - -#define CORE_PRIVATE - -#include "ap_compat.h" -#include "ap_config_auto.h" -#include "ap_config.h" -#include "ap_config_layout.h" -#include "ap_listen.h" -#include "ap_mmn.h" -#include "ap_mpm.h" -#include "ap_provider.h" -#include "ap_regkey.h" -#include "ap_release.h" -#include "http_config.h" -#include "http_connection.h" -#include "http_core.h" -#include "httpd.h" -#include "http_log.h" -#include "http_main.h" -#include "http_protocol.h" -#include "http_request.h" -#include "http_vhost.h" -#include "mpm_common.h" -#include "pcreposix.h" -#include "rfc1413.h" -#include "scoreboard.h" -#include "util_cfgtree.h" -#include "util_charset.h" -#include "util_ebcdic.h" -#include "util_filter.h" -#include "util_ldap.h" -#include "util_md5.h" -#include "util_script.h" -#include "util_time.h" -#include "util_xml.h" -#include "mod_core.h" -#include "os.h" -#include "unixd.h" -#include "apr_allocator.h" -#include "apr_atomic.h" -#include "apr_compat.h" -#include "apr_dso.h" -#include "apr_env.h" -#include "apr_errno.h" -#include "apr_file_info.h" -#include "apr_file_io.h" -#include "apr_fnmatch.h" -#include "apr_general.h" -#include "apr_getopt.h" -#include "apr_global_mutex.h" -#include "apr.h" -#include "apr_hash.h" -#include "apr_inherit.h" -#include "apr_lib.h" -#include "apr_mmap.h" -#include "apr_network_io.h" -#include "apr_poll.h" -#include "apr_pools.h" -#include "apr_portable.h" -#include "apr_proc_mutex.h" -#include "apr_ring.h" -#include "apr_shm.h" -#include "apr_signal.h" -#include "apr_strings.h" -#include "apr_support.h" -#include "apr_tables.h" -#include "apr_thread_cond.h" -#include "apr_thread_mutex.h" -#include "apr_thread_proc.h" -#include "apr_thread_rwlock.h" -#include "apr_time.h" -#include "apr_user.h" -#include "apr_version.h" -#include "apr_want.h" -#include "apr_anylock.h" -#include "apr_base64.h" -#include "apr_buckets.h" -#include "apr_date.h" -#include "apr_dbm.h" -#include "apr_hooks.h" -#include "apr_ldap.h" -#include "apr_ldap_url.h" -#include "apr_md4.h" -#include "apr_md5.h" -#include "apr_optional.h" -#include "apr_optional_hooks.h" -#include "apr_queue.h" -#include "apr_reslist.h" -#include "apr_rmm.h" -#include "apr_sdbm.h" -#include "apr_sha1.h" -#include "apr_strmatch.h" -#include "apr_uri.h" -#include "apr_uuid.h" -#include "apr_xlate.h" -#include "apr_xml.h" -#include "apu_compat.h" -#include "apu.h" -#include "apu_version.h" -#include "apu_want.h" - -const void *ap_ugly_hack = NULL; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/ap_listen.h - */ -const void *ap_hack_ap_set_receive_buffer_size = (const void *)ap_set_receive_buffer_size; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/ap_mpm.h - */ -const void *ap_hack_ap_mpm_run = (const void *)ap_mpm_run; -const void *ap_hack_ap_graceful_stop_signalled = (const void *)ap_graceful_stop_signalled; -const void *ap_hack_ap_os_create_privileged_process = (const void *)ap_os_create_privileged_process; -const void *ap_hack_ap_mpm_query = (const void *)ap_mpm_query; -#if AP_ENABLE_EXCEPTION_HOOK -const void *ap_hack_ap_hook_fatal_exception = (const void *)ap_hook_fatal_exception; -const void *ap_hack_ap_hook_get_fatal_exception = (const void *)ap_hook_get_fatal_exception; -const void *ap_hack_ap_run_fatal_exception = (const void *)ap_run_fatal_exception; -#endif /*AP_ENABLE_EXCEPTION_HOOK*/ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/ap_provider.h - */ -const void *ap_hack_ap_register_provider = (const void *)ap_register_provider; -const void *ap_hack_ap_lookup_provider = (const void *)ap_lookup_provider; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/ap_regkey.h - */ -#if defined(WIN32) || defined(DOXYGEN) -const void *ap_hack_ap_regkey_const = (const void *)ap_regkey_const; -const void *ap_hack_ap_regkey_open = (const void *)ap_regkey_open; -const void *ap_hack_ap_regkey_close = (const void *)ap_regkey_close; -const void *ap_hack_ap_regkey_remove = (const void *)ap_regkey_remove; -const void *ap_hack_ap_regkey_value_get = (const void *)ap_regkey_value_get; -const void *ap_hack_ap_regkey_value_set = (const void *)ap_regkey_value_set; -const void *ap_hack_ap_regkey_value_raw_get = (const void *)ap_regkey_value_raw_get; -const void *ap_hack_ap_regkey_value_raw_set = (const void *)ap_regkey_value_raw_set; -const void *ap_hack_ap_regkey_value_array_get = (const void *)ap_regkey_value_array_get; -const void *ap_hack_ap_regkey_value_array_set = (const void *)ap_regkey_value_array_set; -const void *ap_hack_ap_regkey_value_remove = (const void *)ap_regkey_value_remove; -#endif /* def WIN32 || def DOXYGEN */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_config.h - */ -const void *ap_hack_ap_get_module_config = (const void *)ap_get_module_config; -const void *ap_hack_ap_set_module_config = (const void *)ap_set_module_config; -const void *ap_hack_ap_set_string_slot = (const void *)ap_set_string_slot; -const void *ap_hack_ap_set_int_slot = (const void *)ap_set_int_slot; -const void *ap_hack_ap_method_is_limited = (const void *)ap_method_is_limited; -const void *ap_hack_ap_set_string_slot_lower = (const void *)ap_set_string_slot_lower; -const void *ap_hack_ap_set_flag_slot = (const void *)ap_set_flag_slot; -const void *ap_hack_ap_set_file_slot = (const void *)ap_set_file_slot; -const void *ap_hack_ap_set_deprecated = (const void *)ap_set_deprecated; -const void *ap_hack_ap_server_root_relative = (const void *)ap_server_root_relative; -const void *ap_hack_ap_add_module = (const void *)ap_add_module; -const void *ap_hack_ap_remove_module = (const void *)ap_remove_module; -const void *ap_hack_ap_add_loaded_module = (const void *)ap_add_loaded_module; -const void *ap_hack_ap_remove_loaded_module = (const void *)ap_remove_loaded_module; -const void *ap_hack_ap_add_named_module = (const void *)ap_add_named_module; -const void *ap_hack_ap_find_module_name = (const void *)ap_find_module_name; -const void *ap_hack_ap_find_linked_module = (const void *)ap_find_linked_module; -const void *ap_hack_ap_pcfg_openfile = (const void *)ap_pcfg_openfile; -const void *ap_hack_ap_pcfg_open_custom = (const void *)ap_pcfg_open_custom; -const void *ap_hack_ap_cfg_getline = (const void *)ap_cfg_getline; -const void *ap_hack_ap_cfg_getc = (const void *)ap_cfg_getc; -const void *ap_hack_ap_cfg_closefile = (const void *)ap_cfg_closefile; -const void *ap_hack_ap_soak_end_container = (const void *)ap_soak_end_container; -const void *ap_hack_ap_build_cont_config = (const void *)ap_build_cont_config; -const void *ap_hack_ap_build_config = (const void *)ap_build_config; -const void *ap_hack_ap_walk_config = (const void *)ap_walk_config; -const void *ap_hack_ap_check_cmd_context = (const void *)ap_check_cmd_context; -#ifdef CORE_PRIVATE -const void *ap_hack_ap_single_module_configure = (const void *)ap_single_module_configure; -const void *ap_hack_ap_setup_prelinked_modules = (const void *)ap_setup_prelinked_modules; -const void *ap_hack_ap_show_directives = (const void *)ap_show_directives; -const void *ap_hack_ap_show_modules = (const void *)ap_show_modules; -const void *ap_hack_ap_show_mpm = (const void *)ap_show_mpm; -const void *ap_hack_ap_read_config = (const void *)ap_read_config; -const void *ap_hack_ap_run_rewrite_args = (const void *)ap_run_rewrite_args; -const void *ap_hack_ap_register_hooks = (const void *)ap_register_hooks; -const void *ap_hack_ap_fixup_virtual_hosts = (const void *)ap_fixup_virtual_hosts; -const void *ap_hack_ap_create_request_config = (const void *)ap_create_request_config; -const void *ap_hack_ap_create_per_dir_config = (const void *)ap_create_per_dir_config; -const void *ap_hack_ap_merge_per_dir_configs = (const void *)ap_merge_per_dir_configs; -const void *ap_hack_ap_create_conn_config = (const void *)ap_create_conn_config; -const void *ap_hack_ap_parse_htaccess = (const void *)ap_parse_htaccess; -const void *ap_hack_ap_init_virtual_host = (const void *)ap_init_virtual_host; -const void *ap_hack_ap_process_resource_config = (const void *)ap_process_resource_config; -const void *ap_hack_ap_process_config_tree = (const void *)ap_process_config_tree; -const void *ap_hack_ap_invoke_handler = (const void *)ap_invoke_handler; -const void *ap_hack_ap_find_command = (const void *)ap_find_command; -const void *ap_hack_ap_find_command_in_modules = (const void *)ap_find_command_in_modules; -const void *ap_hack_ap_set_config_vectors = (const void *)ap_set_config_vectors; -#endif -const void *ap_hack_ap_hook_header_parser = (const void *)ap_hook_header_parser; -const void *ap_hack_ap_hook_get_header_parser = (const void *)ap_hook_get_header_parser; -const void *ap_hack_ap_run_header_parser = (const void *)ap_run_header_parser; -const void *ap_hack_ap_hook_pre_config = (const void *)ap_hook_pre_config; -const void *ap_hack_ap_hook_get_pre_config = (const void *)ap_hook_get_pre_config; -const void *ap_hack_ap_run_pre_config = (const void *)ap_run_pre_config; -const void *ap_hack_ap_hook_post_config = (const void *)ap_hook_post_config; -const void *ap_hack_ap_hook_get_post_config = (const void *)ap_hook_get_post_config; -const void *ap_hack_ap_run_post_config = (const void *)ap_run_post_config; -const void *ap_hack_ap_hook_open_logs = (const void *)ap_hook_open_logs; -const void *ap_hack_ap_hook_get_open_logs = (const void *)ap_hook_get_open_logs; -const void *ap_hack_ap_run_open_logs = (const void *)ap_run_open_logs; -const void *ap_hack_ap_hook_child_init = (const void *)ap_hook_child_init; -const void *ap_hack_ap_hook_get_child_init = (const void *)ap_hook_get_child_init; -const void *ap_hack_ap_run_child_init = (const void *)ap_run_child_init; -const void *ap_hack_ap_hook_handler = (const void *)ap_hook_handler; -const void *ap_hack_ap_hook_get_handler = (const void *)ap_hook_get_handler; -const void *ap_hack_ap_run_handler = (const void *)ap_run_handler; -const void *ap_hack_ap_hook_quick_handler = (const void *)ap_hook_quick_handler; -const void *ap_hack_ap_hook_get_quick_handler = (const void *)ap_hook_get_quick_handler; -const void *ap_hack_ap_run_quick_handler = (const void *)ap_run_quick_handler; -const void *ap_hack_ap_hook_optional_fn_retrieve = (const void *)ap_hook_optional_fn_retrieve; -const void *ap_hack_ap_hook_get_optional_fn_retrieve = (const void *)ap_hook_get_optional_fn_retrieve; -const void *ap_hack_ap_run_optional_fn_retrieve = (const void *)ap_run_optional_fn_retrieve; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_connection.h - */ -#ifdef CORE_PRIVATE -const void *ap_hack_ap_process_connection = (const void *)ap_process_connection; -const void *ap_hack_ap_flush_conn = (const void *)ap_flush_conn; -const void *ap_hack_ap_lingering_close = (const void *)ap_lingering_close; -#endif -const void *ap_hack_ap_hook_create_connection = (const void *)ap_hook_create_connection; -const void *ap_hack_ap_hook_get_create_connection = (const void *)ap_hook_get_create_connection; -const void *ap_hack_ap_run_create_connection = (const void *)ap_run_create_connection; -const void *ap_hack_ap_hook_pre_connection = (const void *)ap_hook_pre_connection; -const void *ap_hack_ap_hook_get_pre_connection = (const void *)ap_hook_get_pre_connection; -const void *ap_hack_ap_run_pre_connection = (const void *)ap_run_pre_connection; -const void *ap_hack_ap_hook_process_connection = (const void *)ap_hook_process_connection; -const void *ap_hack_ap_hook_get_process_connection = (const void *)ap_hook_get_process_connection; -const void *ap_hack_ap_run_process_connection = (const void *)ap_run_process_connection; -const void *ap_hack_ap_bucket_eoc_make = (const void *)ap_bucket_eoc_make; -const void *ap_hack_ap_bucket_eoc_create = (const void *)ap_bucket_eoc_create; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_core.h - */ -const void *ap_hack_ap_allow_options = (const void *)ap_allow_options; -const void *ap_hack_ap_allow_overrides = (const void *)ap_allow_overrides; -const void *ap_hack_ap_default_type = (const void *)ap_default_type; -const void *ap_hack_ap_document_root = (const void *)ap_document_root; -const void *ap_hack_ap_get_remote_host = (const void *)ap_get_remote_host; -const void *ap_hack_ap_get_remote_logname = (const void *)ap_get_remote_logname; -const void *ap_hack_ap_construct_url = (const void *)ap_construct_url; -const void *ap_hack_ap_get_server_name = (const void *)ap_get_server_name; -const void *ap_hack_ap_get_server_port = (const void *)ap_get_server_port; -const void *ap_hack_ap_get_limit_req_body = (const void *)ap_get_limit_req_body; -const void *ap_hack_ap_get_limit_xml_body = (const void *)ap_get_limit_xml_body; -const void *ap_hack_ap_custom_response = (const void *)ap_custom_response; -const void *ap_hack_ap_is_recursion_limit_exceeded = (const void *)ap_is_recursion_limit_exceeded; -const void *ap_hack_ap_exists_config_define = (const void *)ap_exists_config_define; -const void *ap_hack_ap_core_translate = (const void *)ap_core_translate; -const void *ap_hack_ap_auth_type = (const void *)ap_auth_type; -const void *ap_hack_ap_auth_name = (const void *)ap_auth_name; -const void *ap_hack_ap_satisfies = (const void *)ap_satisfies; -const void *ap_hack_ap_requires = (const void *)ap_requires; -#ifdef CORE_PRIVATE -const void *ap_hack_ap_register_request_note = (const void *)ap_register_request_note; -const void *ap_hack_ap_get_request_note = (const void *)ap_get_request_note; -const void *ap_hack_ap_add_per_dir_conf = (const void *)ap_add_per_dir_conf; -const void *ap_hack_ap_add_per_url_conf = (const void *)ap_add_per_url_conf; -const void *ap_hack_ap_add_file_conf = (const void *)ap_add_file_conf; -const void *ap_hack_ap_limit_section = (const void *)ap_limit_section; -#endif -const void *ap_hack_ap_hook_get_mgmt_items = (const void *)ap_hook_get_mgmt_items; -const void *ap_hack_ap_hook_get_get_mgmt_items = (const void *)ap_hook_get_get_mgmt_items; -const void *ap_hack_ap_run_get_mgmt_items = (const void *)ap_run_get_mgmt_items; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/httpd.h - */ -const void *ap_hack_ap_get_server_revision = (const void *)ap_get_server_revision; -const void *ap_hack_ap_get_server_version = (const void *)ap_get_server_version; -const void *ap_hack_ap_add_version_component = (const void *)ap_add_version_component; -const void *ap_hack_ap_get_server_built = (const void *)ap_get_server_built; -const void *ap_hack_ap_field_noparam = (const void *)ap_field_noparam; -const void *ap_hack_ap_ht_time = (const void *)ap_ht_time; -const void *ap_hack_ap_getword = (const void *)ap_getword; -const void *ap_hack_ap_getword_nc = (const void *)ap_getword_nc; -const void *ap_hack_ap_getword_white = (const void *)ap_getword_white; -const void *ap_hack_ap_getword_white_nc = (const void *)ap_getword_white_nc; -const void *ap_hack_ap_getword_nulls = (const void *)ap_getword_nulls; -const void *ap_hack_ap_getword_nulls_nc = (const void *)ap_getword_nulls_nc; -const void *ap_hack_ap_getword_conf = (const void *)ap_getword_conf; -const void *ap_hack_ap_getword_conf_nc = (const void *)ap_getword_conf_nc; -const void *ap_hack_ap_resolve_env = (const void *)ap_resolve_env; -const void *ap_hack_ap_size_list_item = (const void *)ap_size_list_item; -const void *ap_hack_ap_get_list_item = (const void *)ap_get_list_item; -const void *ap_hack_ap_find_list_item = (const void *)ap_find_list_item; -const void *ap_hack_ap_get_token = (const void *)ap_get_token; -const void *ap_hack_ap_find_token = (const void *)ap_find_token; -const void *ap_hack_ap_find_last_token = (const void *)ap_find_last_token; -const void *ap_hack_ap_is_url = (const void *)ap_is_url; -const void *ap_hack_ap_unescape_url = (const void *)ap_unescape_url; -const void *ap_hack_ap_unescape_url_keep2f = (const void *)ap_unescape_url_keep2f; -const void *ap_hack_ap_no2slash = (const void *)ap_no2slash; -const void *ap_hack_ap_getparents = (const void *)ap_getparents; -const void *ap_hack_ap_escape_path_segment = (const void *)ap_escape_path_segment; -const void *ap_hack_ap_os_escape_path = (const void *)ap_os_escape_path; -const void *ap_hack_ap_escape_html = (const void *)ap_escape_html; -const void *ap_hack_ap_escape_logitem = (const void *)ap_escape_logitem; -const void *ap_hack_ap_escape_errorlog_item = (const void *)ap_escape_errorlog_item; -const void *ap_hack_ap_construct_server = (const void *)ap_construct_server; -const void *ap_hack_ap_escape_shell_cmd = (const void *)ap_escape_shell_cmd; -const void *ap_hack_ap_count_dirs = (const void *)ap_count_dirs; -const void *ap_hack_ap_make_dirstr_prefix = (const void *)ap_make_dirstr_prefix; -const void *ap_hack_ap_make_dirstr_parent = (const void *)ap_make_dirstr_parent; -const void *ap_hack_ap_make_full_path = (const void *)ap_make_full_path; -const void *ap_hack_ap_os_is_path_absolute = (const void *)ap_os_is_path_absolute; -const void *ap_hack_ap_is_matchexp = (const void *)ap_is_matchexp; -const void *ap_hack_ap_strcmp_match = (const void *)ap_strcmp_match; -const void *ap_hack_ap_strcasecmp_match = (const void *)ap_strcasecmp_match; -const void *ap_hack_ap_strcasestr = (const void *)ap_strcasestr; -const void *ap_hack_ap_stripprefix = (const void *)ap_stripprefix; -const void *ap_hack_ap_pbase64decode = (const void *)ap_pbase64decode; -const void *ap_hack_ap_pbase64encode = (const void *)ap_pbase64encode; -const void *ap_hack_ap_pregcomp = (const void *)ap_pregcomp; -const void *ap_hack_ap_pregfree = (const void *)ap_pregfree; -const void *ap_hack_ap_regexec = (const void *)ap_regexec; -const void *ap_hack_ap_regerror = (const void *)ap_regerror; -const void *ap_hack_ap_pregsub = (const void *)ap_pregsub; -const void *ap_hack_ap_content_type_tolower = (const void *)ap_content_type_tolower; -const void *ap_hack_ap_str_tolower = (const void *)ap_str_tolower; -const void *ap_hack_ap_ind = (const void *)ap_ind; -const void *ap_hack_ap_rind = (const void *)ap_rind; -const void *ap_hack_ap_escape_quotes = (const void *)ap_escape_quotes; -const void *ap_hack_ap_is_rdirectory = (const void *)ap_is_rdirectory; -const void *ap_hack_ap_is_directory = (const void *)ap_is_directory; -const void *ap_hack_ap_log_assert = (const void *)ap_log_assert; -const void *ap_hack_ap_psignature = (const void *)ap_psignature; -const void *ap_hack_ap_strchr = (const void *)ap_strchr; -const void *ap_hack_ap_strchr_c = (const void *)ap_strchr_c; -const void *ap_hack_ap_strrchr = (const void *)ap_strrchr; -const void *ap_hack_ap_strrchr_c = (const void *)ap_strrchr_c; -const void *ap_hack_ap_strstr = (const void *)ap_strstr; -const void *ap_hack_ap_strstr_c = (const void *)ap_strstr_c; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_log.h - */ -const void *ap_hack_ap_open_stderr_log = (const void *)ap_open_stderr_log; -const void *ap_hack_ap_replace_stderr_log = (const void *)ap_replace_stderr_log; -const void *ap_hack_ap_log_error = (const void *)ap_log_error; -const void *ap_hack_ap_log_perror = (const void *)ap_log_perror; -const void *ap_hack_ap_log_rerror = (const void *)ap_log_rerror; -const void *ap_hack_ap_log_cerror = (const void *)ap_log_cerror; -const void *ap_hack_ap_error_log2stderr = (const void *)ap_error_log2stderr; -const void *ap_hack_ap_log_pid = (const void *)ap_log_pid; -const void *ap_hack_ap_read_pid = (const void *)ap_read_pid; -const void *ap_hack_ap_open_piped_log = (const void *)ap_open_piped_log; -const void *ap_hack_ap_close_piped_log = (const void *)ap_close_piped_log; -const void *ap_hack_ap_hook_error_log = (const void *)ap_hook_error_log; -const void *ap_hack_ap_hook_get_error_log = (const void *)ap_hook_get_error_log; -const void *ap_hack_ap_run_error_log = (const void *)ap_run_error_log; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_protocol.h - */ -const void *ap_hack_ap_hook_insert_error_filter = (const void *)ap_hook_insert_error_filter; -const void *ap_hack_ap_hook_get_insert_error_filter = (const void *)ap_hook_get_insert_error_filter; -const void *ap_hack_ap_run_insert_error_filter = (const void *)ap_run_insert_error_filter; -const void *ap_hack_ap_get_mime_headers = (const void *)ap_get_mime_headers; -const void *ap_hack_ap_get_mime_headers_core = (const void *)ap_get_mime_headers_core; -const void *ap_hack_ap_finalize_request_protocol = (const void *)ap_finalize_request_protocol; -const void *ap_hack_ap_send_error_response = (const void *)ap_send_error_response; -const void *ap_hack_ap_set_content_length = (const void *)ap_set_content_length; -const void *ap_hack_ap_set_keepalive = (const void *)ap_set_keepalive; -const void *ap_hack_ap_rationalize_mtime = (const void *)ap_rationalize_mtime; -const void *ap_hack_ap_make_content_type = (const void *)ap_make_content_type; -#ifdef CORE_PRIVATE -const void *ap_hack_ap_setup_make_content_type = (const void *)ap_setup_make_content_type; -#endif /* CORE_PRIVATE */ -const void *ap_hack_ap_make_etag = (const void *)ap_make_etag; -const void *ap_hack_ap_set_etag = (const void *)ap_set_etag; -const void *ap_hack_ap_set_last_modified = (const void *)ap_set_last_modified; -const void *ap_hack_ap_meets_conditions = (const void *)ap_meets_conditions; -const void *ap_hack_ap_send_fd = (const void *)ap_send_fd; -#if APR_HAS_MMAP -const void *ap_hack_ap_send_mmap = (const void *)ap_send_mmap; -#endif -const void *ap_hack_ap_method_register = (const void *)ap_method_register; -const void *ap_hack_ap_method_registry_init = (const void *)ap_method_registry_init; -const void *ap_hack_ap_make_method_list = (const void *)ap_make_method_list; -const void *ap_hack_ap_copy_method_list = (const void *)ap_copy_method_list; -const void *ap_hack_ap_method_list_do = (const void *)ap_method_list_do; -const void *ap_hack_ap_method_list_vdo = (const void *)ap_method_list_vdo; -const void *ap_hack_ap_method_in_list = (const void *)ap_method_in_list; -const void *ap_hack_ap_method_list_add = (const void *)ap_method_list_add; -const void *ap_hack_ap_method_list_remove = (const void *)ap_method_list_remove; -const void *ap_hack_ap_clear_method_list = (const void *)ap_clear_method_list; -const void *ap_hack_ap_set_content_type = (const void *)ap_set_content_type; -const void *ap_hack_ap_rputc = (const void *)ap_rputc; -const void *ap_hack_ap_rputs = (const void *)ap_rputs; -const void *ap_hack_ap_rwrite = (const void *)ap_rwrite; -const void *ap_hack_ap_rvputs = (const void *)ap_rvputs; -const void *ap_hack_ap_vrprintf = (const void *)ap_vrprintf; -const void *ap_hack_ap_rprintf = (const void *)ap_rprintf; -const void *ap_hack_ap_rflush = (const void *)ap_rflush; -const void *ap_hack_ap_index_of_response = (const void *)ap_index_of_response; -const void *ap_hack_ap_get_status_line = (const void *)ap_get_status_line; -const void *ap_hack_ap_setup_client_block = (const void *)ap_setup_client_block; -const void *ap_hack_ap_should_client_block = (const void *)ap_should_client_block; -const void *ap_hack_ap_get_client_block = (const void *)ap_get_client_block; -const void *ap_hack_ap_discard_request_body = (const void *)ap_discard_request_body; -const void *ap_hack_ap_note_auth_failure = (const void *)ap_note_auth_failure; -const void *ap_hack_ap_note_basic_auth_failure = (const void *)ap_note_basic_auth_failure; -const void *ap_hack_ap_note_digest_auth_failure = (const void *)ap_note_digest_auth_failure; -const void *ap_hack_ap_get_basic_auth_pw = (const void *)ap_get_basic_auth_pw; -const void *ap_hack_ap_parse_uri = (const void *)ap_parse_uri; -const void *ap_hack_ap_getline = (const void *)ap_getline; -#if APR_CHARSET_EBCDIC -const void *ap_hack_ap_rgetline = (const void *)ap_rgetline; -#else /* ASCII box */ -#endif -const void *ap_hack_ap_rgetline_core = (const void *)ap_rgetline_core; -const void *ap_hack_ap_method_number_of = (const void *)ap_method_number_of; -const void *ap_hack_ap_method_name_of = (const void *)ap_method_name_of; -const void *ap_hack_ap_hook_post_read_request = (const void *)ap_hook_post_read_request; -const void *ap_hack_ap_hook_get_post_read_request = (const void *)ap_hook_get_post_read_request; -const void *ap_hack_ap_run_post_read_request = (const void *)ap_run_post_read_request; -const void *ap_hack_ap_hook_log_transaction = (const void *)ap_hook_log_transaction; -const void *ap_hack_ap_hook_get_log_transaction = (const void *)ap_hook_get_log_transaction; -const void *ap_hack_ap_run_log_transaction = (const void *)ap_run_log_transaction; -const void *ap_hack_ap_hook_http_method = (const void *)ap_hook_http_method; -const void *ap_hack_ap_hook_get_http_method = (const void *)ap_hook_get_http_method; -const void *ap_hack_ap_run_http_method = (const void *)ap_run_http_method; -const void *ap_hack_ap_hook_default_port = (const void *)ap_hook_default_port; -const void *ap_hack_ap_hook_get_default_port = (const void *)ap_hook_get_default_port; -const void *ap_hack_ap_run_default_port = (const void *)ap_run_default_port; -const void *ap_hack_ap_bucket_error_make = (const void *)ap_bucket_error_make; -const void *ap_hack_ap_bucket_error_create = (const void *)ap_bucket_error_create; -const void *ap_hack_ap_byterange_filter = (const void *)ap_byterange_filter; -const void *ap_hack_ap_http_header_filter = (const void *)ap_http_header_filter; -const void *ap_hack_ap_content_length_filter = (const void *)ap_content_length_filter; -const void *ap_hack_ap_old_write_filter = (const void *)ap_old_write_filter; -const void *ap_hack_ap_set_sub_req_protocol = (const void *)ap_set_sub_req_protocol; -const void *ap_hack_ap_finalize_sub_req_protocol = (const void *)ap_finalize_sub_req_protocol; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_request.h - */ -const void *ap_hack_ap_process_request_internal = (const void *)ap_process_request_internal; -const void *ap_hack_ap_sub_req_lookup_uri = (const void *)ap_sub_req_lookup_uri; -const void *ap_hack_ap_sub_req_lookup_file = (const void *)ap_sub_req_lookup_file; -const void *ap_hack_ap_sub_req_lookup_dirent = (const void *)ap_sub_req_lookup_dirent; -const void *ap_hack_ap_sub_req_method_uri = (const void *)ap_sub_req_method_uri; -const void *ap_hack_ap_sub_req_output_filter = (const void *)ap_sub_req_output_filter; -const void *ap_hack_ap_run_sub_req = (const void *)ap_run_sub_req; -const void *ap_hack_ap_destroy_sub_req = (const void *)ap_destroy_sub_req; -const void *ap_hack_ap_internal_redirect = (const void *)ap_internal_redirect; -const void *ap_hack_ap_internal_redirect_handler = (const void *)ap_internal_redirect_handler; -const void *ap_hack_ap_internal_fast_redirect = (const void *)ap_internal_fast_redirect; -const void *ap_hack_ap_some_auth_required = (const void *)ap_some_auth_required; -const void *ap_hack_ap_is_initial_req = (const void *)ap_is_initial_req; -const void *ap_hack_ap_update_mtime = (const void *)ap_update_mtime; -const void *ap_hack_ap_allow_methods = (const void *)ap_allow_methods; -const void *ap_hack_ap_allow_standard_methods = (const void *)ap_allow_standard_methods; -#ifdef CORE_PRIVATE -const void *ap_hack_ap_die = (const void *)ap_die; -#endif -const void *ap_hack_ap_hook_create_request = (const void *)ap_hook_create_request; -const void *ap_hack_ap_hook_get_create_request = (const void *)ap_hook_get_create_request; -const void *ap_hack_ap_run_create_request = (const void *)ap_run_create_request; -const void *ap_hack_ap_hook_translate_name = (const void *)ap_hook_translate_name; -const void *ap_hack_ap_hook_get_translate_name = (const void *)ap_hook_get_translate_name; -const void *ap_hack_ap_run_translate_name = (const void *)ap_run_translate_name; -const void *ap_hack_ap_hook_map_to_storage = (const void *)ap_hook_map_to_storage; -const void *ap_hack_ap_hook_get_map_to_storage = (const void *)ap_hook_get_map_to_storage; -const void *ap_hack_ap_run_map_to_storage = (const void *)ap_run_map_to_storage; -const void *ap_hack_ap_hook_check_user_id = (const void *)ap_hook_check_user_id; -const void *ap_hack_ap_hook_get_check_user_id = (const void *)ap_hook_get_check_user_id; -const void *ap_hack_ap_run_check_user_id = (const void *)ap_run_check_user_id; -const void *ap_hack_ap_hook_fixups = (const void *)ap_hook_fixups; -const void *ap_hack_ap_hook_get_fixups = (const void *)ap_hook_get_fixups; -const void *ap_hack_ap_run_fixups = (const void *)ap_run_fixups; -const void *ap_hack_ap_hook_type_checker = (const void *)ap_hook_type_checker; -const void *ap_hack_ap_hook_get_type_checker = (const void *)ap_hook_get_type_checker; -const void *ap_hack_ap_run_type_checker = (const void *)ap_run_type_checker; -const void *ap_hack_ap_hook_access_checker = (const void *)ap_hook_access_checker; -const void *ap_hack_ap_hook_get_access_checker = (const void *)ap_hook_get_access_checker; -const void *ap_hack_ap_run_access_checker = (const void *)ap_run_access_checker; -const void *ap_hack_ap_hook_auth_checker = (const void *)ap_hook_auth_checker; -const void *ap_hack_ap_hook_get_auth_checker = (const void *)ap_hook_get_auth_checker; -const void *ap_hack_ap_run_auth_checker = (const void *)ap_run_auth_checker; -const void *ap_hack_ap_hook_insert_filter = (const void *)ap_hook_insert_filter; -const void *ap_hack_ap_hook_get_insert_filter = (const void *)ap_hook_get_insert_filter; -const void *ap_hack_ap_run_insert_filter = (const void *)ap_run_insert_filter; -const void *ap_hack_ap_location_walk = (const void *)ap_location_walk; -const void *ap_hack_ap_directory_walk = (const void *)ap_directory_walk; -const void *ap_hack_ap_file_walk = (const void *)ap_file_walk; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/http_vhost.h - */ -const void *ap_hack_ap_init_vhost_config = (const void *)ap_init_vhost_config; -const void *ap_hack_ap_fini_vhost_config = (const void *)ap_fini_vhost_config; -const void *ap_hack_ap_vhost_iterate_given_conn = (const void *)ap_vhost_iterate_given_conn; -const void *ap_hack_ap_update_vhost_given_ip = (const void *)ap_update_vhost_given_ip; -const void *ap_hack_ap_update_vhost_from_headers = (const void *)ap_update_vhost_from_headers; -const void *ap_hack_ap_matches_request_vhost = (const void *)ap_matches_request_vhost; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/mpm_common.h - */ -#ifdef HAVE_GETPWNAM -const void *ap_hack_ap_uname2id = (const void *)ap_uname2id; -#endif -#ifdef HAVE_GETGRNAM -const void *ap_hack_ap_gname2id = (const void *)ap_gname2id; -#endif -#ifdef AP_MPM_USES_POD -const void *ap_hack_ap_mpm_pod_open = (const void *)ap_mpm_pod_open; -const void *ap_hack_ap_mpm_pod_check = (const void *)ap_mpm_pod_check; -const void *ap_hack_ap_mpm_pod_close = (const void *)ap_mpm_pod_close; -const void *ap_hack_ap_mpm_pod_signal = (const void *)ap_mpm_pod_signal; -const void *ap_hack_ap_mpm_pod_killpg = (const void *)ap_mpm_pod_killpg; -#endif - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/scoreboard.h - */ -const void *ap_hack_ap_exists_scoreboard_image = (const void *)ap_exists_scoreboard_image; -const void *ap_hack_ap_increment_counts = (const void *)ap_increment_counts; -const void *ap_hack_ap_calc_scoreboard_size = (const void *)ap_calc_scoreboard_size; -const void *ap_hack_ap_create_sb_handle = (const void *)ap_create_sb_handle; -const void *ap_hack_find_child_by_pid = (const void *)find_child_by_pid; -const void *ap_hack_ap_update_child_status = (const void *)ap_update_child_status; -const void *ap_hack_ap_update_child_status_from_indexes = (const void *)ap_update_child_status_from_indexes; -const void *ap_hack_ap_get_scoreboard_worker = (const void *)ap_get_scoreboard_worker; -const void *ap_hack_ap_get_scoreboard_process = (const void *)ap_get_scoreboard_process; -const void *ap_hack_ap_get_scoreboard_global = (const void *)ap_get_scoreboard_global; -const void *ap_hack_ap_hook_pre_mpm = (const void *)ap_hook_pre_mpm; -const void *ap_hack_ap_hook_get_pre_mpm = (const void *)ap_hook_get_pre_mpm; -const void *ap_hack_ap_run_pre_mpm = (const void *)ap_run_pre_mpm; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/util_filter.h - */ -const void *ap_hack_ap_get_brigade = (const void *)ap_get_brigade; -const void *ap_hack_ap_pass_brigade = (const void *)ap_pass_brigade; -const void *ap_hack_ap_register_input_filter = (const void *)ap_register_input_filter; -const void *ap_hack_ap_register_output_filter = (const void *)ap_register_output_filter; -const void *ap_hack_ap_add_input_filter = (const void *)ap_add_input_filter; -const void *ap_hack_ap_add_input_filter_handle = (const void *)ap_add_input_filter_handle; -const void *ap_hack_ap_get_input_filter_handle = (const void *)ap_get_input_filter_handle; -const void *ap_hack_ap_add_output_filter = (const void *)ap_add_output_filter; -const void *ap_hack_ap_add_output_filter_handle = (const void *)ap_add_output_filter_handle; -const void *ap_hack_ap_get_output_filter_handle = (const void *)ap_get_output_filter_handle; -const void *ap_hack_ap_remove_input_filter = (const void *)ap_remove_input_filter; -const void *ap_hack_ap_remove_output_filter = (const void *)ap_remove_output_filter; -const void *ap_hack_ap_save_brigade = (const void *)ap_save_brigade; -const void *ap_hack_ap_filter_flush = (const void *)ap_filter_flush; -const void *ap_hack_ap_fflush = (const void *)ap_fflush; -const void *ap_hack_ap_fputstrs = (const void *)ap_fputstrs; -const void *ap_hack_ap_fprintf = (const void *)ap_fprintf; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/util_md5.h - */ -const void *ap_hack_ap_md5 = (const void *)ap_md5; -const void *ap_hack_ap_md5_binary = (const void *)ap_md5_binary; -const void *ap_hack_ap_md5contextTo64 = (const void *)ap_md5contextTo64; -const void *ap_hack_ap_md5digest = (const void *)ap_md5digest; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/util_script.h - */ -const void *ap_hack_ap_create_environment = (const void *)ap_create_environment; -const void *ap_hack_ap_find_path_info = (const void *)ap_find_path_info; -const void *ap_hack_ap_add_cgi_vars = (const void *)ap_add_cgi_vars; -const void *ap_hack_ap_add_common_vars = (const void *)ap_add_common_vars; -const void *ap_hack_ap_scan_script_header_err = (const void *)ap_scan_script_header_err; -const void *ap_hack_ap_scan_script_header_err_brigade = (const void *)ap_scan_script_header_err_brigade; -const void *ap_hack_ap_scan_script_header_err_strs = (const void *)ap_scan_script_header_err_strs; -const void *ap_hack_ap_scan_script_header_err_core = (const void *)ap_scan_script_header_err_core; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/util_time.h - */ -const void *ap_hack_ap_explode_recent_localtime = (const void *)ap_explode_recent_localtime; -const void *ap_hack_ap_explode_recent_gmt = (const void *)ap_explode_recent_gmt; -const void *ap_hack_ap_recent_ctime = (const void *)ap_recent_ctime; -const void *ap_hack_ap_recent_rfc822_date = (const void *)ap_recent_rfc822_date; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/include/util_xml.h - */ -const void *ap_hack_ap_xml_parse_input = (const void *)ap_xml_parse_input; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/modules/http/mod_core.h - */ -const void *ap_hack_ap_basic_http_header = (const void *)ap_basic_http_header; -const void *ap_hack_ap_send_http_trace = (const void *)ap_send_http_trace; -const void *ap_hack_ap_send_http_options = (const void *)ap_send_http_options; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/os/unix/unixd.h - */ -const void *ap_hack_ap_hook_get_suexec_identity = (const void *)ap_hook_get_suexec_identity; -const void *ap_hack_ap_hook_get_get_suexec_identity = (const void *)ap_hook_get_get_suexec_identity; -const void *ap_hack_ap_run_get_suexec_identity = (const void *)ap_run_get_suexec_identity; -const void *ap_hack_unixd_setup_child = (const void *)unixd_setup_child; -const void *ap_hack_unixd_pre_config = (const void *)unixd_pre_config; -const void *ap_hack_unixd_set_user = (const void *)unixd_set_user; -const void *ap_hack_unixd_set_group = (const void *)unixd_set_group; -#if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS) -const void *ap_hack_unixd_set_rlimit = (const void *)unixd_set_rlimit; -#endif -const void *ap_hack_unixd_set_proc_mutex_perms = (const void *)unixd_set_proc_mutex_perms; -const void *ap_hack_unixd_set_global_mutex_perms = (const void *)unixd_set_global_mutex_perms; -const void *ap_hack_unixd_accept = (const void *)unixd_accept; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_allocator.h - */ -const void *ap_hack_apr_allocator_create = (const void *)apr_allocator_create; -const void *ap_hack_apr_allocator_destroy = (const void *)apr_allocator_destroy; -const void *ap_hack_apr_allocator_alloc = (const void *)apr_allocator_alloc; -const void *ap_hack_apr_allocator_free = (const void *)apr_allocator_free; -const void *ap_hack_apr_allocator_owner_set = (const void *)apr_allocator_owner_set; -const void *ap_hack_apr_allocator_set_owner = (const void *)apr_allocator_set_owner; -const void *ap_hack_apr_allocator_owner_get = (const void *)apr_allocator_owner_get; -const void *ap_hack_apr_allocator_get_owner = (const void *)apr_allocator_get_owner; -const void *ap_hack_apr_allocator_max_free_set = (const void *)apr_allocator_max_free_set; -const void *ap_hack_apr_allocator_set_max_free = (const void *)apr_allocator_set_max_free; -#if APR_HAS_THREADS -const void *ap_hack_apr_allocator_mutex_set = (const void *)apr_allocator_mutex_set; -const void *ap_hack_apr_allocator_set_mutex = (const void *)apr_allocator_set_mutex; -const void *ap_hack_apr_allocator_mutex_get = (const void *)apr_allocator_mutex_get; -const void *ap_hack_apr_allocator_get_mutex = (const void *)apr_allocator_get_mutex; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_dso.h - */ -#if APR_HAS_DSO || defined(DOXYGEN) -const void *ap_hack_apr_dso_load = (const void *)apr_dso_load; -const void *ap_hack_apr_dso_unload = (const void *)apr_dso_unload; -const void *ap_hack_apr_dso_sym = (const void *)apr_dso_sym; -const void *ap_hack_apr_dso_error = (const void *)apr_dso_error; -#endif /* APR_HAS_DSO */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_env.h - */ -const void *ap_hack_apr_env_get = (const void *)apr_env_get; -const void *ap_hack_apr_env_set = (const void *)apr_env_set; -const void *ap_hack_apr_env_delete = (const void *)apr_env_delete; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_errno.h - */ -const void *ap_hack_apr_strerror = (const void *)apr_strerror; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_file_info.h - */ -const void *ap_hack_apr_stat = (const void *)apr_stat; -const void *ap_hack_apr_lstat = (const void *)apr_lstat; -const void *ap_hack_apr_dir_open = (const void *)apr_dir_open; -const void *ap_hack_apr_dir_close = (const void *)apr_dir_close; -const void *ap_hack_apr_dir_read = (const void *)apr_dir_read; -const void *ap_hack_apr_dir_rewind = (const void *)apr_dir_rewind; -const void *ap_hack_apr_filepath_root = (const void *)apr_filepath_root; -const void *ap_hack_apr_filepath_merge = (const void *)apr_filepath_merge; -const void *ap_hack_apr_filepath_list_split = (const void *)apr_filepath_list_split; -const void *ap_hack_apr_filepath_list_merge = (const void *)apr_filepath_list_merge; -const void *ap_hack_apr_filepath_get = (const void *)apr_filepath_get; -const void *ap_hack_apr_filepath_set = (const void *)apr_filepath_set; -const void *ap_hack_apr_filepath_encoding = (const void *)apr_filepath_encoding; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_file_io.h - */ -const void *ap_hack_apr_file_open = (const void *)apr_file_open; -const void *ap_hack_apr_file_close = (const void *)apr_file_close; -const void *ap_hack_apr_file_remove = (const void *)apr_file_remove; -const void *ap_hack_apr_file_rename = (const void *)apr_file_rename; -const void *ap_hack_apr_file_copy = (const void *)apr_file_copy; -const void *ap_hack_apr_file_append = (const void *)apr_file_append; -const void *ap_hack_apr_file_eof = (const void *)apr_file_eof; -const void *ap_hack_apr_file_open_stderr = (const void *)apr_file_open_stderr; -const void *ap_hack_apr_file_open_stdout = (const void *)apr_file_open_stdout; -const void *ap_hack_apr_file_open_stdin = (const void *)apr_file_open_stdin; -const void *ap_hack_apr_file_read = (const void *)apr_file_read; -const void *ap_hack_apr_file_write = (const void *)apr_file_write; -const void *ap_hack_apr_file_writev = (const void *)apr_file_writev; -const void *ap_hack_apr_file_read_full = (const void *)apr_file_read_full; -const void *ap_hack_apr_file_write_full = (const void *)apr_file_write_full; -const void *ap_hack_apr_file_putc = (const void *)apr_file_putc; -const void *ap_hack_apr_file_getc = (const void *)apr_file_getc; -const void *ap_hack_apr_file_ungetc = (const void *)apr_file_ungetc; -const void *ap_hack_apr_file_gets = (const void *)apr_file_gets; -const void *ap_hack_apr_file_puts = (const void *)apr_file_puts; -const void *ap_hack_apr_file_flush = (const void *)apr_file_flush; -const void *ap_hack_apr_file_dup = (const void *)apr_file_dup; -const void *ap_hack_apr_file_dup2 = (const void *)apr_file_dup2; -const void *ap_hack_apr_file_setaside = (const void *)apr_file_setaside; -const void *ap_hack_apr_file_seek = (const void *)apr_file_seek; -const void *ap_hack_apr_file_pipe_create = (const void *)apr_file_pipe_create; -const void *ap_hack_apr_file_namedpipe_create = (const void *)apr_file_namedpipe_create; -const void *ap_hack_apr_file_pipe_timeout_get = (const void *)apr_file_pipe_timeout_get; -const void *ap_hack_apr_file_pipe_timeout_set = (const void *)apr_file_pipe_timeout_set; -const void *ap_hack_apr_file_lock = (const void *)apr_file_lock; -const void *ap_hack_apr_file_unlock = (const void *)apr_file_unlock; -const void *ap_hack_apr_file_name_get = (const void *)apr_file_name_get; -const void *ap_hack_apr_file_data_get = (const void *)apr_file_data_get; -const void *ap_hack_apr_file_data_set = (const void *)apr_file_data_set; -const void *ap_hack_apr_file_printf = (const void *)apr_file_printf; -const void *ap_hack_apr_file_perms_set = (const void *)apr_file_perms_set; -const void *ap_hack_apr_file_attrs_set = (const void *)apr_file_attrs_set; -const void *ap_hack_apr_file_mtime_set = (const void *)apr_file_mtime_set; -const void *ap_hack_apr_dir_make = (const void *)apr_dir_make; -const void *ap_hack_apr_dir_make_recursive = (const void *)apr_dir_make_recursive; -const void *ap_hack_apr_dir_remove = (const void *)apr_dir_remove; -const void *ap_hack_apr_file_info_get = (const void *)apr_file_info_get; -const void *ap_hack_apr_file_trunc = (const void *)apr_file_trunc; -const void *ap_hack_apr_file_flags_get = (const void *)apr_file_flags_get; -const void *ap_hack_apr_file_pool_get = (const void *)apr_file_pool_get; -const void *ap_hack_apr_file_inherit_set = (const void *)apr_file_inherit_set; -const void *ap_hack_apr_file_set_inherit = (const void *)apr_file_set_inherit; -const void *ap_hack_apr_file_inherit_unset = (const void *)apr_file_inherit_unset; -const void *ap_hack_apr_file_unset_inherit = (const void *)apr_file_unset_inherit; -const void *ap_hack_apr_file_mktemp = (const void *)apr_file_mktemp; -const void *ap_hack_apr_temp_dir_get = (const void *)apr_temp_dir_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_fnmatch.h - */ -const void *ap_hack_apr_fnmatch = (const void *)apr_fnmatch; -const void *ap_hack_apr_fnmatch_test = (const void *)apr_fnmatch_test; -const void *ap_hack_apr_is_fnmatch = (const void *)apr_is_fnmatch; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_general.h - */ -const void *ap_hack_apr_initialize = (const void *)apr_initialize; -const void *ap_hack_apr_app_initialize = (const void *)apr_app_initialize; -const void *ap_hack_apr_terminate = (const void *)apr_terminate; -const void *ap_hack_apr_terminate2 = (const void *)apr_terminate2; -#if APR_HAS_RANDOM || defined(DOXYGEN) -#ifdef APR_ENABLE_FOR_1_0 -const void *ap_hack_apr_generate_random_bytes = (const void *)apr_generate_random_bytes; -#else -const void *ap_hack_apr_generate_random_bytes = (const void *)apr_generate_random_bytes; -#endif -#endif - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_getopt.h - */ -const void *ap_hack_apr_getopt_init = (const void *)apr_getopt_init; -const void *ap_hack_apr_getopt = (const void *)apr_getopt; -const void *ap_hack_apr_getopt_long = (const void *)apr_getopt_long; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_global_mutex.h - */ -#if !APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN) -const void *ap_hack_apr_global_mutex_create = (const void *)apr_global_mutex_create; -const void *ap_hack_apr_global_mutex_child_init = (const void *)apr_global_mutex_child_init; -const void *ap_hack_apr_global_mutex_lock = (const void *)apr_global_mutex_lock; -const void *ap_hack_apr_global_mutex_trylock = (const void *)apr_global_mutex_trylock; -const void *ap_hack_apr_global_mutex_unlock = (const void *)apr_global_mutex_unlock; -const void *ap_hack_apr_global_mutex_destroy = (const void *)apr_global_mutex_destroy; -const void *ap_hack_apr_global_mutex_pool_get = (const void *)apr_global_mutex_pool_get; -#else /* APR_PROC_MUTEX_IS_GLOBAL */ -#endif - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_hash.h - */ -const void *ap_hack_apr_hash_make = (const void *)apr_hash_make; -const void *ap_hack_apr_hash_copy = (const void *)apr_hash_copy; -const void *ap_hack_apr_hash_set = (const void *)apr_hash_set; -const void *ap_hack_apr_hash_get = (const void *)apr_hash_get; -const void *ap_hack_apr_hash_first = (const void *)apr_hash_first; -const void *ap_hack_apr_hash_next = (const void *)apr_hash_next; -const void *ap_hack_apr_hash_this = (const void *)apr_hash_this; -const void *ap_hack_apr_hash_count = (const void *)apr_hash_count; -const void *ap_hack_apr_hash_overlay = (const void *)apr_hash_overlay; -const void *ap_hack_apr_hash_merge = (const void *)apr_hash_merge; -const void *ap_hack_apr_hash_pool_get = (const void *)apr_hash_pool_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_lib.h - */ -const void *ap_hack_apr_filepath_name_get = (const void *)apr_filepath_name_get; -const void *ap_hack_apr_filename_of_pathname = (const void *)apr_filename_of_pathname; -const void *ap_hack_apr_vformatter = (const void *)apr_vformatter; -const void *ap_hack_apr_password_get = (const void *)apr_password_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_mmap.h - */ -#if APR_HAS_MMAP || defined(DOXYGEN) -const void *ap_hack_apr_mmap_create = (const void *)apr_mmap_create; -const void *ap_hack_apr_mmap_dup = (const void *)apr_mmap_dup; -#if defined(DOXYGEN) -const void *ap_hack_apr_mmap_setaside = (const void *)apr_mmap_setaside; -#else -#endif /* DOXYGEN */ -const void *ap_hack_apr_mmap_delete = (const void *)apr_mmap_delete; -const void *ap_hack_apr_mmap_offset = (const void *)apr_mmap_offset; -#endif /* APR_HAS_MMAP */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_network_io.h - */ -const void *ap_hack_apr_socket_create = (const void *)apr_socket_create; -const void *ap_hack_apr_socket_create_ex = (const void *)apr_socket_create_ex; -const void *ap_hack_apr_socket_shutdown = (const void *)apr_socket_shutdown; -const void *ap_hack_apr_shutdown = (const void *)apr_shutdown; -const void *ap_hack_apr_socket_close = (const void *)apr_socket_close; -const void *ap_hack_apr_socket_bind = (const void *)apr_socket_bind; -const void *ap_hack_apr_bind = (const void *)apr_bind; -const void *ap_hack_apr_socket_listen = (const void *)apr_socket_listen; -const void *ap_hack_apr_listen = (const void *)apr_listen; -const void *ap_hack_apr_socket_accept = (const void *)apr_socket_accept; -const void *ap_hack_apr_accept = (const void *)apr_accept; -const void *ap_hack_apr_socket_connect = (const void *)apr_socket_connect; -const void *ap_hack_apr_connect = (const void *)apr_connect; -const void *ap_hack_apr_sockaddr_info_get = (const void *)apr_sockaddr_info_get; -const void *ap_hack_apr_getnameinfo = (const void *)apr_getnameinfo; -const void *ap_hack_apr_parse_addr_port = (const void *)apr_parse_addr_port; -const void *ap_hack_apr_gethostname = (const void *)apr_gethostname; -const void *ap_hack_apr_socket_data_get = (const void *)apr_socket_data_get; -const void *ap_hack_apr_socket_data_set = (const void *)apr_socket_data_set; -const void *ap_hack_apr_socket_send = (const void *)apr_socket_send; -const void *ap_hack_apr_send = (const void *)apr_send; -const void *ap_hack_apr_socket_sendv = (const void *)apr_socket_sendv; -const void *ap_hack_apr_sendv = (const void *)apr_sendv; -const void *ap_hack_apr_socket_sendto = (const void *)apr_socket_sendto; -const void *ap_hack_apr_sendto = (const void *)apr_sendto; -const void *ap_hack_apr_socket_recvfrom = (const void *)apr_socket_recvfrom; -const void *ap_hack_apr_recvfrom = (const void *)apr_recvfrom; -#if APR_HAS_SENDFILE || defined(DOXYGEN) -const void *ap_hack_apr_socket_sendfile = (const void *)apr_socket_sendfile; -const void *ap_hack_apr_sendfile = (const void *)apr_sendfile; -#endif /* APR_HAS_SENDFILE */ -const void *ap_hack_apr_socket_recv = (const void *)apr_socket_recv; -const void *ap_hack_apr_recv = (const void *)apr_recv; -const void *ap_hack_apr_socket_opt_set = (const void *)apr_socket_opt_set; -const void *ap_hack_apr_setsocketopt = (const void *)apr_setsocketopt; -const void *ap_hack_apr_socket_timeout_set = (const void *)apr_socket_timeout_set; -const void *ap_hack_apr_socket_opt_get = (const void *)apr_socket_opt_get; -const void *ap_hack_apr_getsocketopt = (const void *)apr_getsocketopt; -const void *ap_hack_apr_socket_timeout_get = (const void *)apr_socket_timeout_get; -const void *ap_hack_apr_socket_atmark = (const void *)apr_socket_atmark; -const void *ap_hack_apr_socket_addr_get = (const void *)apr_socket_addr_get; -const void *ap_hack_apr_sockaddr_port_set = (const void *)apr_sockaddr_port_set; -const void *ap_hack_apr_sockaddr_port_get = (const void *)apr_sockaddr_port_get; -const void *ap_hack_apr_sockaddr_ip_set = (const void *)apr_sockaddr_ip_set; -const void *ap_hack_apr_sockaddr_ip_get = (const void *)apr_sockaddr_ip_get; -const void *ap_hack_apr_sockaddr_equal = (const void *)apr_sockaddr_equal; -#if APR_FILES_AS_SOCKETS || defined(DOXYGEN) -const void *ap_hack_apr_socket_from_file = (const void *)apr_socket_from_file; -#endif /* APR_FILES_AS_SOCKETS */ -const void *ap_hack_apr_getservbyname = (const void *)apr_getservbyname; -const void *ap_hack_apr_ipsubnet_create = (const void *)apr_ipsubnet_create; -const void *ap_hack_apr_ipsubnet_test = (const void *)apr_ipsubnet_test; -const void *ap_hack_apr_socket_protocol_get = (const void *)apr_socket_protocol_get; -const void *ap_hack_apr_socket_inherit_set = (const void *)apr_socket_inherit_set; -const void *ap_hack_apr_socket_set_inherit = (const void *)apr_socket_set_inherit; -const void *ap_hack_apr_socket_inherit_unset = (const void *)apr_socket_inherit_unset; -const void *ap_hack_apr_socket_unset_inherit = (const void *)apr_socket_unset_inherit; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_poll.h - */ -const void *ap_hack_apr_poll_setup = (const void *)apr_poll_setup; -const void *ap_hack_apr_poll = (const void *)apr_poll; -const void *ap_hack_apr_poll_socket_add = (const void *)apr_poll_socket_add; -const void *ap_hack_apr_poll_socket_mask = (const void *)apr_poll_socket_mask; -const void *ap_hack_apr_poll_socket_remove = (const void *)apr_poll_socket_remove; -const void *ap_hack_apr_poll_socket_clear = (const void *)apr_poll_socket_clear; -const void *ap_hack_apr_poll_revents_get = (const void *)apr_poll_revents_get; -const void *ap_hack_apr_pollset_create = (const void *)apr_pollset_create; -const void *ap_hack_apr_pollset_destroy = (const void *)apr_pollset_destroy; -const void *ap_hack_apr_pollset_add = (const void *)apr_pollset_add; -const void *ap_hack_apr_pollset_remove = (const void *)apr_pollset_remove; -const void *ap_hack_apr_pollset_poll = (const void *)apr_pollset_poll; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_pools.h - */ -const void *ap_hack_apr_pool_initialize = (const void *)apr_pool_initialize; -const void *ap_hack_apr_pool_terminate = (const void *)apr_pool_terminate; -const void *ap_hack_apr_pool_create_ex = (const void *)apr_pool_create_ex; -const void *ap_hack_apr_pool_create_ex_debug = (const void *)apr_pool_create_ex_debug; -#if defined(DOXYGEN) -const void *ap_hack_apr_pool_create = (const void *)apr_pool_create; -#else -#endif -const void *ap_hack_apr_pool_allocator_get = (const void *)apr_pool_allocator_get; -const void *ap_hack_apr_pool_clear = (const void *)apr_pool_clear; -const void *ap_hack_apr_pool_clear_debug = (const void *)apr_pool_clear_debug; -const void *ap_hack_apr_pool_destroy = (const void *)apr_pool_destroy; -const void *ap_hack_apr_pool_destroy_debug = (const void *)apr_pool_destroy_debug; -const void *ap_hack_apr_palloc = (const void *)apr_palloc; -const void *ap_hack_apr_palloc_debug = (const void *)apr_palloc_debug; -#if defined(DOXYGEN) -const void *ap_hack_apr_pcalloc = (const void *)apr_pcalloc; -#elif !APR_POOL_DEBUG -#endif -const void *ap_hack_apr_pcalloc_debug = (const void *)apr_pcalloc_debug; -const void *ap_hack_apr_pool_abort_set = (const void *)apr_pool_abort_set; -const void *ap_hack_apr_pool_set_abort = (const void *)apr_pool_set_abort; -const void *ap_hack_apr_pool_abort_get = (const void *)apr_pool_abort_get; -const void *ap_hack_apr_pool_get_abort = (const void *)apr_pool_get_abort; -const void *ap_hack_apr_pool_parent_get = (const void *)apr_pool_parent_get; -const void *ap_hack_apr_pool_get_parent = (const void *)apr_pool_get_parent; -const void *ap_hack_apr_pool_is_ancestor = (const void *)apr_pool_is_ancestor; -const void *ap_hack_apr_pool_tag = (const void *)apr_pool_tag; -const void *ap_hack_apr_pool_userdata_set = (const void *)apr_pool_userdata_set; -const void *ap_hack_apr_pool_userdata_setn = (const void *)apr_pool_userdata_setn; -const void *ap_hack_apr_pool_userdata_get = (const void *)apr_pool_userdata_get; -const void *ap_hack_apr_pool_cleanup_register = (const void *)apr_pool_cleanup_register; -const void *ap_hack_apr_pool_cleanup_kill = (const void *)apr_pool_cleanup_kill; -const void *ap_hack_apr_pool_child_cleanup_set = (const void *)apr_pool_child_cleanup_set; -const void *ap_hack_apr_pool_cleanup_run = (const void *)apr_pool_cleanup_run; -const void *ap_hack_apr_pool_cleanup_null = (const void *)apr_pool_cleanup_null; -const void *ap_hack_apr_pool_cleanup_for_exec = (const void *)apr_pool_cleanup_for_exec; -#if APR_POOL_DEBUG || defined(DOXYGEN) -const void *ap_hack_apr_pool_join = (const void *)apr_pool_join; -const void *ap_hack_apr_pool_find = (const void *)apr_pool_find; -const void *ap_hack_apr_pool_num_bytes = (const void *)apr_pool_num_bytes; -const void *ap_hack_apr_pool_lock = (const void *)apr_pool_lock; -#else /* APR_POOL_DEBUG or DOXYGEN */ -#endif /* APR_POOL_DEBUG or DOXYGEN */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_portable.h - */ -#if APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN) -#else -const void *ap_hack_apr_os_global_mutex_get = (const void *)apr_os_global_mutex_get; -#endif -const void *ap_hack_apr_os_file_get = (const void *)apr_os_file_get; -const void *ap_hack_apr_os_dir_get = (const void *)apr_os_dir_get; -const void *ap_hack_apr_os_sock_get = (const void *)apr_os_sock_get; -const void *ap_hack_apr_os_proc_mutex_get = (const void *)apr_os_proc_mutex_get; -const void *ap_hack_apr_os_exp_time_get = (const void *)apr_os_exp_time_get; -const void *ap_hack_apr_os_imp_time_get = (const void *)apr_os_imp_time_get; -const void *ap_hack_apr_os_shm_get = (const void *)apr_os_shm_get; -#if APR_HAS_THREADS || defined(DOXYGEN) -const void *ap_hack_apr_os_thread_get = (const void *)apr_os_thread_get; -const void *ap_hack_apr_os_threadkey_get = (const void *)apr_os_threadkey_get; -const void *ap_hack_apr_os_thread_put = (const void *)apr_os_thread_put; -const void *ap_hack_apr_os_threadkey_put = (const void *)apr_os_threadkey_put; -const void *ap_hack_apr_os_thread_current = (const void *)apr_os_thread_current; -const void *ap_hack_apr_os_thread_equal = (const void *)apr_os_thread_equal; -#endif /* APR_HAS_THREADS */ -const void *ap_hack_apr_os_file_put = (const void *)apr_os_file_put; -const void *ap_hack_apr_os_pipe_put = (const void *)apr_os_pipe_put; -const void *ap_hack_apr_os_pipe_put_ex = (const void *)apr_os_pipe_put_ex; -const void *ap_hack_apr_os_dir_put = (const void *)apr_os_dir_put; -const void *ap_hack_apr_os_sock_put = (const void *)apr_os_sock_put; -const void *ap_hack_apr_os_sock_make = (const void *)apr_os_sock_make; -const void *ap_hack_apr_os_proc_mutex_put = (const void *)apr_os_proc_mutex_put; -const void *ap_hack_apr_os_imp_time_put = (const void *)apr_os_imp_time_put; -const void *ap_hack_apr_os_exp_time_put = (const void *)apr_os_exp_time_put; -const void *ap_hack_apr_os_shm_put = (const void *)apr_os_shm_put; -#if APR_HAS_DSO || defined(DOXYGEN) -const void *ap_hack_apr_os_dso_handle_put = (const void *)apr_os_dso_handle_put; -const void *ap_hack_apr_os_dso_handle_get = (const void *)apr_os_dso_handle_get; -#if APR_HAS_OS_UUID -const void *ap_hack_apr_os_uuid_get = (const void *)apr_os_uuid_get; -#endif -#endif /* APR_HAS_DSO */ -const void *ap_hack_apr_os_default_encoding = (const void *)apr_os_default_encoding; -const void *ap_hack_apr_os_locale_encoding = (const void *)apr_os_locale_encoding; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_proc_mutex.h - */ -const void *ap_hack_apr_proc_mutex_create = (const void *)apr_proc_mutex_create; -const void *ap_hack_apr_proc_mutex_child_init = (const void *)apr_proc_mutex_child_init; -const void *ap_hack_apr_proc_mutex_lock = (const void *)apr_proc_mutex_lock; -const void *ap_hack_apr_proc_mutex_trylock = (const void *)apr_proc_mutex_trylock; -const void *ap_hack_apr_proc_mutex_unlock = (const void *)apr_proc_mutex_unlock; -const void *ap_hack_apr_proc_mutex_destroy = (const void *)apr_proc_mutex_destroy; -const void *ap_hack_apr_proc_mutex_cleanup = (const void *)apr_proc_mutex_cleanup; -const void *ap_hack_apr_proc_mutex_lockfile = (const void *)apr_proc_mutex_lockfile; -const void *ap_hack_apr_proc_mutex_name = (const void *)apr_proc_mutex_name; -const void *ap_hack_apr_proc_mutex_defname = (const void *)apr_proc_mutex_defname; -const void *ap_hack_apr_proc_mutex_pool_get = (const void *)apr_proc_mutex_pool_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_shm.h - */ -const void *ap_hack_apr_shm_create = (const void *)apr_shm_create; -const void *ap_hack_apr_shm_destroy = (const void *)apr_shm_destroy; -const void *ap_hack_apr_shm_attach = (const void *)apr_shm_attach; -const void *ap_hack_apr_shm_detach = (const void *)apr_shm_detach; -const void *ap_hack_apr_shm_baseaddr_get = (const void *)apr_shm_baseaddr_get; -const void *ap_hack_apr_shm_size_get = (const void *)apr_shm_size_get; -const void *ap_hack_apr_shm_pool_get = (const void *)apr_shm_pool_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_signal.h - */ -#if APR_HAVE_SIGACTION || defined(DOXYGEN) -const void *ap_hack_apr_signal = (const void *)apr_signal; -#else /* !APR_HAVE_SIGACTION */ -#endif -const void *ap_hack_apr_signal_description_get = (const void *)apr_signal_description_get; -const void *ap_hack_apr_signal_get_description = (const void *)apr_signal_get_description; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_strings.h - */ -const void *ap_hack_apr_strnatcmp = (const void *)apr_strnatcmp; -const void *ap_hack_apr_strnatcasecmp = (const void *)apr_strnatcasecmp; -const void *ap_hack_apr_pstrdup = (const void *)apr_pstrdup; -const void *ap_hack_apr_pstrmemdup = (const void *)apr_pstrmemdup; -const void *ap_hack_apr_pstrndup = (const void *)apr_pstrndup; -const void *ap_hack_apr_pmemdup = (const void *)apr_pmemdup; -const void *ap_hack_apr_pstrcat = (const void *)apr_pstrcat; -const void *ap_hack_apr_pstrcatv = (const void *)apr_pstrcatv; -const void *ap_hack_apr_pvsprintf = (const void *)apr_pvsprintf; -const void *ap_hack_apr_psprintf = (const void *)apr_psprintf; -const void *ap_hack_apr_cpystrn = (const void *)apr_cpystrn; -const void *ap_hack_apr_collapse_spaces = (const void *)apr_collapse_spaces; -const void *ap_hack_apr_tokenize_to_argv = (const void *)apr_tokenize_to_argv; -const void *ap_hack_apr_strtok = (const void *)apr_strtok; -const void *ap_hack_apr_snprintf = (const void *)apr_snprintf; -const void *ap_hack_apr_vsnprintf = (const void *)apr_vsnprintf; -const void *ap_hack_apr_itoa = (const void *)apr_itoa; -const void *ap_hack_apr_ltoa = (const void *)apr_ltoa; -const void *ap_hack_apr_off_t_toa = (const void *)apr_off_t_toa; -const void *ap_hack_apr_strtoi64 = (const void *)apr_strtoi64; -const void *ap_hack_apr_atoi64 = (const void *)apr_atoi64; -const void *ap_hack_apr_strfsize = (const void *)apr_strfsize; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_tables.h - */ -const void *ap_hack_apr_table_elts = (const void *)apr_table_elts; -const void *ap_hack_apr_is_empty_table = (const void *)apr_is_empty_table; -const void *ap_hack_apr_is_empty_array = (const void *)apr_is_empty_array; -const void *ap_hack_apr_array_make = (const void *)apr_array_make; -const void *ap_hack_apr_array_push = (const void *)apr_array_push; -const void *ap_hack_apr_array_pop = (const void *)apr_array_pop; -const void *ap_hack_apr_array_cat = (const void *)apr_array_cat; -const void *ap_hack_apr_array_copy = (const void *)apr_array_copy; -const void *ap_hack_apr_array_copy_hdr = (const void *)apr_array_copy_hdr; -const void *ap_hack_apr_array_append = (const void *)apr_array_append; -const void *ap_hack_apr_array_pstrcat = (const void *)apr_array_pstrcat; -const void *ap_hack_apr_table_make = (const void *)apr_table_make; -const void *ap_hack_apr_table_copy = (const void *)apr_table_copy; -const void *ap_hack_apr_table_clear = (const void *)apr_table_clear; -const void *ap_hack_apr_table_get = (const void *)apr_table_get; -const void *ap_hack_apr_table_set = (const void *)apr_table_set; -const void *ap_hack_apr_table_setn = (const void *)apr_table_setn; -const void *ap_hack_apr_table_unset = (const void *)apr_table_unset; -const void *ap_hack_apr_table_merge = (const void *)apr_table_merge; -const void *ap_hack_apr_table_mergen = (const void *)apr_table_mergen; -const void *ap_hack_apr_table_add = (const void *)apr_table_add; -const void *ap_hack_apr_table_addn = (const void *)apr_table_addn; -const void *ap_hack_apr_table_overlay = (const void *)apr_table_overlay; -const void *ap_hack_apr_table_do = (const void *)apr_table_do; -const void *ap_hack_apr_table_vdo = (const void *)apr_table_vdo; -const void *ap_hack_apr_table_overlap = (const void *)apr_table_overlap; -const void *ap_hack_apr_table_compress = (const void *)apr_table_compress; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_cond.h - */ -#if APR_HAS_THREADS || defined(DOXYGEN) -const void *ap_hack_apr_thread_cond_create = (const void *)apr_thread_cond_create; -const void *ap_hack_apr_thread_cond_wait = (const void *)apr_thread_cond_wait; -const void *ap_hack_apr_thread_cond_timedwait = (const void *)apr_thread_cond_timedwait; -const void *ap_hack_apr_thread_cond_signal = (const void *)apr_thread_cond_signal; -const void *ap_hack_apr_thread_cond_broadcast = (const void *)apr_thread_cond_broadcast; -const void *ap_hack_apr_thread_cond_destroy = (const void *)apr_thread_cond_destroy; -const void *ap_hack_apr_thread_cond_pool_get = (const void *)apr_thread_cond_pool_get; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_mutex.h - */ -#if APR_HAS_THREADS || defined(DOXYGEN) -const void *ap_hack_apr_thread_mutex_create = (const void *)apr_thread_mutex_create; -const void *ap_hack_apr_thread_mutex_lock = (const void *)apr_thread_mutex_lock; -const void *ap_hack_apr_thread_mutex_trylock = (const void *)apr_thread_mutex_trylock; -const void *ap_hack_apr_thread_mutex_unlock = (const void *)apr_thread_mutex_unlock; -const void *ap_hack_apr_thread_mutex_destroy = (const void *)apr_thread_mutex_destroy; -const void *ap_hack_apr_thread_mutex_pool_get = (const void *)apr_thread_mutex_pool_get; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_proc.h - */ -#if APR_HAS_THREADS -const void *ap_hack_apr_threadattr_create = (const void *)apr_threadattr_create; -const void *ap_hack_apr_threadattr_detach_set = (const void *)apr_threadattr_detach_set; -const void *ap_hack_apr_threadattr_detach_get = (const void *)apr_threadattr_detach_get; -const void *ap_hack_apr_threadattr_stacksize_set = (const void *)apr_threadattr_stacksize_set; -const void *ap_hack_apr_thread_create = (const void *)apr_thread_create; -const void *ap_hack_apr_thread_exit = (const void *)apr_thread_exit; -const void *ap_hack_apr_thread_join = (const void *)apr_thread_join; -const void *ap_hack_apr_thread_yield = (const void *)apr_thread_yield; -const void *ap_hack_apr_thread_once_init = (const void *)apr_thread_once_init; -const void *ap_hack_apr_thread_once = (const void *)apr_thread_once; -const void *ap_hack_apr_thread_detach = (const void *)apr_thread_detach; -const void *ap_hack_apr_thread_data_get = (const void *)apr_thread_data_get; -const void *ap_hack_apr_thread_data_set = (const void *)apr_thread_data_set; -const void *ap_hack_apr_threadkey_private_create = (const void *)apr_threadkey_private_create; -const void *ap_hack_apr_threadkey_private_get = (const void *)apr_threadkey_private_get; -const void *ap_hack_apr_threadkey_private_set = (const void *)apr_threadkey_private_set; -const void *ap_hack_apr_threadkey_private_delete = (const void *)apr_threadkey_private_delete; -const void *ap_hack_apr_threadkey_data_get = (const void *)apr_threadkey_data_get; -const void *ap_hack_apr_threadkey_data_set = (const void *)apr_threadkey_data_set; -#endif -const void *ap_hack_apr_procattr_create = (const void *)apr_procattr_create; -const void *ap_hack_apr_procattr_io_set = (const void *)apr_procattr_io_set; -const void *ap_hack_apr_procattr_child_in_set = (const void *)apr_procattr_child_in_set; -const void *ap_hack_apr_procattr_child_out_set = (const void *)apr_procattr_child_out_set; -const void *ap_hack_apr_procattr_child_err_set = (const void *)apr_procattr_child_err_set; -const void *ap_hack_apr_procattr_dir_set = (const void *)apr_procattr_dir_set; -const void *ap_hack_apr_procattr_cmdtype_set = (const void *)apr_procattr_cmdtype_set; -const void *ap_hack_apr_procattr_detach_set = (const void *)apr_procattr_detach_set; -#if APR_HAVE_STRUCT_RLIMIT -const void *ap_hack_apr_procattr_limit_set = (const void *)apr_procattr_limit_set; -#endif -const void *ap_hack_apr_procattr_child_errfn_set = (const void *)apr_procattr_child_errfn_set; -const void *ap_hack_apr_procattr_error_check_set = (const void *)apr_procattr_error_check_set; -const void *ap_hack_apr_procattr_addrspace_set = (const void *)apr_procattr_addrspace_set; -#if APR_HAS_FORK -const void *ap_hack_apr_proc_fork = (const void *)apr_proc_fork; -#endif -const void *ap_hack_apr_proc_create = (const void *)apr_proc_create; -const void *ap_hack_apr_proc_wait = (const void *)apr_proc_wait; -const void *ap_hack_apr_proc_wait_all_procs = (const void *)apr_proc_wait_all_procs; -const void *ap_hack_apr_proc_detach = (const void *)apr_proc_detach; -const void *ap_hack_apr_proc_other_child_register = (const void *)apr_proc_other_child_register; -const void *ap_hack_apr_proc_other_child_unregister = (const void *)apr_proc_other_child_unregister; -const void *ap_hack_apr_proc_other_child_alert = (const void *)apr_proc_other_child_alert; -const void *ap_hack_apr_proc_other_child_refresh = (const void *)apr_proc_other_child_refresh; -const void *ap_hack_apr_proc_other_child_refresh_all = (const void *)apr_proc_other_child_refresh_all; -const void *ap_hack_apr_proc_other_child_check = (const void *)apr_proc_other_child_check; -const void *ap_hack_apr_proc_other_child_read = (const void *)apr_proc_other_child_read; -const void *ap_hack_apr_proc_kill = (const void *)apr_proc_kill; -const void *ap_hack_apr_pool_note_subprocess = (const void *)apr_pool_note_subprocess; -#if APR_HAS_THREADS -#if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) -const void *ap_hack_apr_setup_signal_thread = (const void *)apr_setup_signal_thread; -const void *ap_hack_apr_signal_thread = (const void *)apr_signal_thread; -#endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */ -const void *ap_hack_apr_thread_pool_get = (const void *)apr_thread_pool_get; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_thread_rwlock.h - */ -#if APR_HAS_THREADS -const void *ap_hack_apr_thread_rwlock_create = (const void *)apr_thread_rwlock_create; -const void *ap_hack_apr_thread_rwlock_rdlock = (const void *)apr_thread_rwlock_rdlock; -const void *ap_hack_apr_thread_rwlock_tryrdlock = (const void *)apr_thread_rwlock_tryrdlock; -const void *ap_hack_apr_thread_rwlock_wrlock = (const void *)apr_thread_rwlock_wrlock; -const void *ap_hack_apr_thread_rwlock_trywrlock = (const void *)apr_thread_rwlock_trywrlock; -const void *ap_hack_apr_thread_rwlock_unlock = (const void *)apr_thread_rwlock_unlock; -const void *ap_hack_apr_thread_rwlock_destroy = (const void *)apr_thread_rwlock_destroy; -const void *ap_hack_apr_thread_rwlock_pool_get = (const void *)apr_thread_rwlock_pool_get; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_time.h - */ -const void *ap_hack_apr_time_now = (const void *)apr_time_now; -const void *ap_hack_apr_time_ansi_put = (const void *)apr_time_ansi_put; -const void *ap_hack_apr_time_exp_tz = (const void *)apr_time_exp_tz; -const void *ap_hack_apr_explode_time = (const void *)apr_explode_time; -const void *ap_hack_apr_time_exp_gmt = (const void *)apr_time_exp_gmt; -const void *ap_hack_apr_time_exp_lt = (const void *)apr_time_exp_lt; -const void *ap_hack_apr_explode_localtime = (const void *)apr_explode_localtime; -const void *ap_hack_apr_time_exp_get = (const void *)apr_time_exp_get; -const void *ap_hack_apr_time_exp_gmt_get = (const void *)apr_time_exp_gmt_get; -const void *ap_hack_apr_implode_gmt = (const void *)apr_implode_gmt; -const void *ap_hack_apr_sleep = (const void *)apr_sleep; -const void *ap_hack_apr_rfc822_date = (const void *)apr_rfc822_date; -const void *ap_hack_apr_ctime = (const void *)apr_ctime; -const void *ap_hack_apr_strftime = (const void *)apr_strftime; -const void *ap_hack_apr_time_clock_hires = (const void *)apr_time_clock_hires; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_user.h - */ -#if APR_HAS_USER -const void *ap_hack_apr_uid_current = (const void *)apr_uid_current; -const void *ap_hack_apr_current_userid = (const void *)apr_current_userid; -const void *ap_hack_apr_uid_name_get = (const void *)apr_uid_name_get; -const void *ap_hack_apr_get_username = (const void *)apr_get_username; -const void *ap_hack_apr_uid_get = (const void *)apr_uid_get; -const void *ap_hack_apr_get_userid = (const void *)apr_get_userid; -const void *ap_hack_apr_uid_homepath_get = (const void *)apr_uid_homepath_get; -const void *ap_hack_apr_get_home_directory = (const void *)apr_get_home_directory; -#if defined(WIN32) -const void *ap_hack_apr_uid_compare = (const void *)apr_uid_compare; -const void *ap_hack_apr_compare_users = (const void *)apr_compare_users; -#else -#endif -const void *ap_hack_apr_gid_name_get = (const void *)apr_gid_name_get; -const void *ap_hack_apr_group_name_get = (const void *)apr_group_name_get; -const void *ap_hack_apr_get_groupname = (const void *)apr_get_groupname; -const void *ap_hack_apr_gid_get = (const void *)apr_gid_get; -const void *ap_hack_apr_get_groupid = (const void *)apr_get_groupid; -#if defined(WIN32) -const void *ap_hack_apr_gid_compare = (const void *)apr_gid_compare; -const void *ap_hack_apr_compare_groups = (const void *)apr_compare_groups; -#else -#endif -#endif /* ! APR_HAS_USER */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr/include/apr_version.h - */ -const void *ap_hack_apr_version = (const void *)apr_version; -const void *ap_hack_apr_version_string = (const void *)apr_version_string; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_base64.h - */ -const void *ap_hack_apr_base64_encode_len = (const void *)apr_base64_encode_len; -const void *ap_hack_apr_base64_encode = (const void *)apr_base64_encode; -const void *ap_hack_apr_base64_encode_binary = (const void *)apr_base64_encode_binary; -const void *ap_hack_apr_base64_decode_len = (const void *)apr_base64_decode_len; -const void *ap_hack_apr_base64_decode = (const void *)apr_base64_decode; -const void *ap_hack_apr_base64_decode_binary = (const void *)apr_base64_decode_binary; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_buckets.h - */ -const void *ap_hack_apr_brigade_create = (const void *)apr_brigade_create; -const void *ap_hack_apr_brigade_destroy = (const void *)apr_brigade_destroy; -const void *ap_hack_apr_brigade_cleanup = (const void *)apr_brigade_cleanup; -const void *ap_hack_apr_brigade_split = (const void *)apr_brigade_split; -const void *ap_hack_apr_brigade_partition = (const void *)apr_brigade_partition; -#if APR_NOT_DONE_YET -const void *ap_hack_apr_brigade_consume = (const void *)apr_brigade_consume; -#endif -const void *ap_hack_apr_brigade_length = (const void *)apr_brigade_length; -const void *ap_hack_apr_brigade_flatten = (const void *)apr_brigade_flatten; -const void *ap_hack_apr_brigade_pflatten = (const void *)apr_brigade_pflatten; -const void *ap_hack_apr_brigade_split_line = (const void *)apr_brigade_split_line; -const void *ap_hack_apr_brigade_to_iovec = (const void *)apr_brigade_to_iovec; -const void *ap_hack_apr_brigade_vputstrs = (const void *)apr_brigade_vputstrs; -const void *ap_hack_apr_brigade_write = (const void *)apr_brigade_write; -const void *ap_hack_apr_brigade_writev = (const void *)apr_brigade_writev; -const void *ap_hack_apr_brigade_puts = (const void *)apr_brigade_puts; -const void *ap_hack_apr_brigade_putc = (const void *)apr_brigade_putc; -const void *ap_hack_apr_brigade_putstrs = (const void *)apr_brigade_putstrs; -const void *ap_hack_apr_brigade_printf = (const void *)apr_brigade_printf; -const void *ap_hack_apr_brigade_vprintf = (const void *)apr_brigade_vprintf; -const void *ap_hack_apr_bucket_alloc_create = (const void *)apr_bucket_alloc_create; -const void *ap_hack_apr_bucket_alloc_create_ex = (const void *)apr_bucket_alloc_create_ex; -const void *ap_hack_apr_bucket_alloc_destroy = (const void *)apr_bucket_alloc_destroy; -const void *ap_hack_apr_bucket_alloc = (const void *)apr_bucket_alloc; -const void *ap_hack_apr_bucket_free = (const void *)apr_bucket_free; -const void *ap_hack_apr_bucket_setaside_noop = (const void *)apr_bucket_setaside_noop; -const void *ap_hack_apr_bucket_setaside_notimpl = (const void *)apr_bucket_setaside_notimpl; -const void *ap_hack_apr_bucket_split_notimpl = (const void *)apr_bucket_split_notimpl; -const void *ap_hack_apr_bucket_copy_notimpl = (const void *)apr_bucket_copy_notimpl; -const void *ap_hack_apr_bucket_destroy_noop = (const void *)apr_bucket_destroy_noop; -const void *ap_hack_apr_bucket_simple_split = (const void *)apr_bucket_simple_split; -const void *ap_hack_apr_bucket_simple_copy = (const void *)apr_bucket_simple_copy; -const void *ap_hack_apr_bucket_shared_make = (const void *)apr_bucket_shared_make; -const void *ap_hack_apr_bucket_shared_destroy = (const void *)apr_bucket_shared_destroy; -const void *ap_hack_apr_bucket_shared_split = (const void *)apr_bucket_shared_split; -const void *ap_hack_apr_bucket_shared_copy = (const void *)apr_bucket_shared_copy; -const void *ap_hack_apr_bucket_eos_create = (const void *)apr_bucket_eos_create; -const void *ap_hack_apr_bucket_eos_make = (const void *)apr_bucket_eos_make; -const void *ap_hack_apr_bucket_flush_create = (const void *)apr_bucket_flush_create; -const void *ap_hack_apr_bucket_flush_make = (const void *)apr_bucket_flush_make; -const void *ap_hack_apr_bucket_immortal_create = (const void *)apr_bucket_immortal_create; -const void *ap_hack_apr_bucket_immortal_make = (const void *)apr_bucket_immortal_make; -const void *ap_hack_apr_bucket_transient_create = (const void *)apr_bucket_transient_create; -const void *ap_hack_apr_bucket_transient_make = (const void *)apr_bucket_transient_make; -const void *ap_hack_apr_bucket_heap_create = (const void *)apr_bucket_heap_create; -const void *ap_hack_apr_bucket_heap_make = (const void *)apr_bucket_heap_make; -const void *ap_hack_apr_bucket_pool_create = (const void *)apr_bucket_pool_create; -const void *ap_hack_apr_bucket_pool_make = (const void *)apr_bucket_pool_make; -#if APR_HAS_MMAP -const void *ap_hack_apr_bucket_mmap_create = (const void *)apr_bucket_mmap_create; -const void *ap_hack_apr_bucket_mmap_make = (const void *)apr_bucket_mmap_make; -#endif -const void *ap_hack_apr_bucket_socket_create = (const void *)apr_bucket_socket_create; -const void *ap_hack_apr_bucket_socket_make = (const void *)apr_bucket_socket_make; -const void *ap_hack_apr_bucket_pipe_create = (const void *)apr_bucket_pipe_create; -const void *ap_hack_apr_bucket_pipe_make = (const void *)apr_bucket_pipe_make; -const void *ap_hack_apr_bucket_file_create = (const void *)apr_bucket_file_create; -const void *ap_hack_apr_bucket_file_make = (const void *)apr_bucket_file_make; -const void *ap_hack_apr_bucket_file_enable_mmap = (const void *)apr_bucket_file_enable_mmap; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_date.h - */ -const void *ap_hack_apr_date_checkmask = (const void *)apr_date_checkmask; -const void *ap_hack_apr_date_parse_http = (const void *)apr_date_parse_http; -const void *ap_hack_apr_date_parse_rfc = (const void *)apr_date_parse_rfc; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_dbm.h - */ -const void *ap_hack_apr_dbm_open_ex = (const void *)apr_dbm_open_ex; -const void *ap_hack_apr_dbm_open = (const void *)apr_dbm_open; -const void *ap_hack_apr_dbm_close = (const void *)apr_dbm_close; -const void *ap_hack_apr_dbm_fetch = (const void *)apr_dbm_fetch; -const void *ap_hack_apr_dbm_store = (const void *)apr_dbm_store; -const void *ap_hack_apr_dbm_delete = (const void *)apr_dbm_delete; -const void *ap_hack_apr_dbm_exists = (const void *)apr_dbm_exists; -const void *ap_hack_apr_dbm_firstkey = (const void *)apr_dbm_firstkey; -const void *ap_hack_apr_dbm_nextkey = (const void *)apr_dbm_nextkey; -const void *ap_hack_apr_dbm_freedatum = (const void *)apr_dbm_freedatum; -const void *ap_hack_apr_dbm_geterror = (const void *)apr_dbm_geterror; -const void *ap_hack_apr_dbm_get_usednames_ex = (const void *)apr_dbm_get_usednames_ex; -const void *ap_hack_apr_dbm_get_usednames = (const void *)apr_dbm_get_usednames; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_hooks.h - */ -const void *ap_hack_apr_hook_sort_register = (const void *)apr_hook_sort_register; -const void *ap_hack_apr_hook_sort_all = (const void *)apr_hook_sort_all; -const void *ap_hack_apr_sort_hooks = (const void *)apr_sort_hooks; -const void *ap_hack_apr_hook_debug_show = (const void *)apr_hook_debug_show; -const void *ap_hack_apr_show_hook = (const void *)apr_show_hook; -const void *ap_hack_apr_hook_deregister_all = (const void *)apr_hook_deregister_all; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_ldap_url.h - */ -#if APR_HAS_LDAP -#if APR_HAS_LDAP_URL_PARSE -#else /* ! APR_HAS_LDAP_URL_PARSE */ -const void *ap_hack_apr_ldap_is_ldap_url = (const void *)apr_ldap_is_ldap_url; -const void *ap_hack_apr_ldap_is_ldaps_url = (const void *)apr_ldap_is_ldaps_url; -const void *ap_hack_apr_ldap_is_ldapi_url = (const void *)apr_ldap_is_ldapi_url; -const void *ap_hack_apr_ldap_url_parse = (const void *)apr_ldap_url_parse; -const void *ap_hack_apr_ldap_free_urldesc = (const void *)apr_ldap_free_urldesc; -#endif /* ! APR_HAS_LDAP_URL_PARSE */ -#endif /* APR_HAS_LDAP */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_md4.h - */ -const void *ap_hack_apr_md4_init = (const void *)apr_md4_init; -#if APR_HAS_XLATE -const void *ap_hack_apr_md4_set_xlate = (const void *)apr_md4_set_xlate; -#else -#endif -const void *ap_hack_apr_md4_update = (const void *)apr_md4_update; -const void *ap_hack_apr_md4_final = (const void *)apr_md4_final; -const void *ap_hack_apr_md4 = (const void *)apr_md4; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_md5.h - */ -const void *ap_hack_apr_md5_init = (const void *)apr_md5_init; -const void *ap_hack_apr_md5_set_xlate = (const void *)apr_md5_set_xlate; -const void *ap_hack_apr_md5_update = (const void *)apr_md5_update; -const void *ap_hack_apr_md5_final = (const void *)apr_md5_final; -const void *ap_hack_apr_md5 = (const void *)apr_md5; -const void *ap_hack_apr_md5_encode = (const void *)apr_md5_encode; -const void *ap_hack_apr_password_validate = (const void *)apr_password_validate; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_optional.h - */ -const void *ap_hack_apr_dynamic_fn_register = (const void *)apr_dynamic_fn_register; -const void *ap_hack_apr_register_optional_fn = (const void *)apr_register_optional_fn; -const void *ap_hack_apr_dynamic_fn_retrieve = (const void *)apr_dynamic_fn_retrieve; -const void *ap_hack_apr_retrieve_optional_fn = (const void *)apr_retrieve_optional_fn; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_optional_hooks.h - */ -const void *ap_hack_apr_optional_hook_add = (const void *)apr_optional_hook_add; -const void *ap_hack_apr_optional_hook_get = (const void *)apr_optional_hook_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_queue.h - */ -#if APR_HAS_THREADS -const void *ap_hack_apr_queue_create = (const void *)apr_queue_create; -const void *ap_hack_apr_queue_push = (const void *)apr_queue_push; -const void *ap_hack_apr_queue_pop = (const void *)apr_queue_pop; -const void *ap_hack_apr_queue_trypush = (const void *)apr_queue_trypush; -const void *ap_hack_apr_queue_trypop = (const void *)apr_queue_trypop; -const void *ap_hack_apr_queue_size = (const void *)apr_queue_size; -const void *ap_hack_apr_queue_interrupt_all = (const void *)apr_queue_interrupt_all; -const void *ap_hack_apr_queue_term = (const void *)apr_queue_term; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_reslist.h - */ -#if APR_HAS_THREADS -const void *ap_hack_apr_reslist_create = (const void *)apr_reslist_create; -const void *ap_hack_apr_reslist_destroy = (const void *)apr_reslist_destroy; -const void *ap_hack_apr_reslist_acquire = (const void *)apr_reslist_acquire; -const void *ap_hack_apr_reslist_release = (const void *)apr_reslist_release; -const void *ap_hack_apr_reslist_timeout_set = (const void *)apr_reslist_timeout_set; -const void *ap_hack_apr_reslist_invalidate = (const void *)apr_reslist_invalidate; -#endif /* APR_HAS_THREADS */ - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_rmm.h - */ -const void *ap_hack_apr_rmm_init = (const void *)apr_rmm_init; -const void *ap_hack_apr_rmm_destroy = (const void *)apr_rmm_destroy; -const void *ap_hack_apr_rmm_attach = (const void *)apr_rmm_attach; -const void *ap_hack_apr_rmm_detach = (const void *)apr_rmm_detach; -const void *ap_hack_apr_rmm_malloc = (const void *)apr_rmm_malloc; -const void *ap_hack_apr_rmm_realloc = (const void *)apr_rmm_realloc; -const void *ap_hack_apr_rmm_calloc = (const void *)apr_rmm_calloc; -const void *ap_hack_apr_rmm_free = (const void *)apr_rmm_free; -const void *ap_hack_apr_rmm_addr_get = (const void *)apr_rmm_addr_get; -const void *ap_hack_apr_rmm_offset_get = (const void *)apr_rmm_offset_get; -const void *ap_hack_apr_rmm_overhead_get = (const void *)apr_rmm_overhead_get; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_sdbm.h - */ -const void *ap_hack_apr_sdbm_open = (const void *)apr_sdbm_open; -const void *ap_hack_apr_sdbm_close = (const void *)apr_sdbm_close; -const void *ap_hack_apr_sdbm_lock = (const void *)apr_sdbm_lock; -const void *ap_hack_apr_sdbm_unlock = (const void *)apr_sdbm_unlock; -const void *ap_hack_apr_sdbm_fetch = (const void *)apr_sdbm_fetch; -const void *ap_hack_apr_sdbm_store = (const void *)apr_sdbm_store; -const void *ap_hack_apr_sdbm_delete = (const void *)apr_sdbm_delete; -const void *ap_hack_apr_sdbm_firstkey = (const void *)apr_sdbm_firstkey; -const void *ap_hack_apr_sdbm_nextkey = (const void *)apr_sdbm_nextkey; -const void *ap_hack_apr_sdbm_rdonly = (const void *)apr_sdbm_rdonly; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_sha1.h - */ -const void *ap_hack_apr_sha1_base64 = (const void *)apr_sha1_base64; -const void *ap_hack_apr_sha1_init = (const void *)apr_sha1_init; -const void *ap_hack_apr_sha1_update = (const void *)apr_sha1_update; -const void *ap_hack_apr_sha1_update_binary = (const void *)apr_sha1_update_binary; -const void *ap_hack_apr_sha1_final = (const void *)apr_sha1_final; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_strmatch.h - */ -#if defined(DOXYGEN) -const void *ap_hack_apr_strmatch = (const void *)apr_strmatch; -#else -#endif -const void *ap_hack_apr_strmatch_precompile = (const void *)apr_strmatch_precompile; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_uri.h - */ -const void *ap_hack_apr_uri_port_of_scheme = (const void *)apr_uri_port_of_scheme; -const void *ap_hack_apr_uri_default_port_for_scheme = (const void *)apr_uri_default_port_for_scheme; -const void *ap_hack_apr_uri_unparse = (const void *)apr_uri_unparse; -const void *ap_hack_apr_uri_parse = (const void *)apr_uri_parse; -const void *ap_hack_apr_uri_parse_hostinfo = (const void *)apr_uri_parse_hostinfo; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_uuid.h - */ -const void *ap_hack_apr_uuid_get = (const void *)apr_uuid_get; -const void *ap_hack_apr_uuid_format = (const void *)apr_uuid_format; -const void *ap_hack_apr_uuid_parse = (const void *)apr_uuid_parse; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_xlate.h - */ -const void *ap_hack_apr_xlate_open = (const void *)apr_xlate_open; -const void *ap_hack_apr_xlate_sb_get = (const void *)apr_xlate_sb_get; -const void *ap_hack_apr_xlate_get_sb = (const void *)apr_xlate_get_sb; -const void *ap_hack_apr_xlate_conv_buffer = (const void *)apr_xlate_conv_buffer; -#ifdef APR_NOT_DONE_YET -const void *ap_hack_apr_xlate_conv_char = (const void *)apr_xlate_conv_char; -#endif -const void *ap_hack_apr_xlate_conv_byte = (const void *)apr_xlate_conv_byte; -const void *ap_hack_apr_xlate_close = (const void *)apr_xlate_close; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apr_xml.h - */ -const void *ap_hack_apr_text_append = (const void *)apr_text_append; -const void *ap_hack_apr_xml_parser_create = (const void *)apr_xml_parser_create; -const void *ap_hack_apr_xml_parse_file = (const void *)apr_xml_parse_file; -const void *ap_hack_apr_xml_parser_feed = (const void *)apr_xml_parser_feed; -const void *ap_hack_apr_xml_parser_done = (const void *)apr_xml_parser_done; -const void *ap_hack_apr_xml_parser_geterror = (const void *)apr_xml_parser_geterror; -const void *ap_hack_apr_xml_to_text = (const void *)apr_xml_to_text; -const void *ap_hack_apr_xml_empty_elem = (const void *)apr_xml_empty_elem; -const void *ap_hack_apr_xml_quote_string = (const void *)apr_xml_quote_string; -const void *ap_hack_apr_xml_quote_elem = (const void *)apr_xml_quote_elem; -const void *ap_hack_apr_xml_insert_uri = (const void *)apr_xml_insert_uri; - -/* - * /bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/include/apu_version.h - */ -const void *ap_hack_apu_version = (const void *)apu_version; -const void *ap_hack_apu_version_string = (const void *)apu_version_string; - diff --git a/rubbos/app/httpd-2.0.64/server/exports.lo b/rubbos/app/httpd-2.0.64/server/exports.lo deleted file mode 100644 index 26e7ae67..00000000 --- a/rubbos/app/httpd-2.0.64/server/exports.lo +++ /dev/null @@ -1,12 +0,0 @@ -# exports.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/exports.o' - -# Name of the non-PIC object. -non_pic_object='exports.o' - diff --git a/rubbos/app/httpd-2.0.64/server/exports.o b/rubbos/app/httpd-2.0.64/server/exports.o Binary files differdeleted file mode 100644 index a93c0eed..00000000 --- a/rubbos/app/httpd-2.0.64/server/exports.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/gen_test_char b/rubbos/app/httpd-2.0.64/server/gen_test_char Binary files differdeleted file mode 100755 index 11e1050c..00000000 --- a/rubbos/app/httpd-2.0.64/server/gen_test_char +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/gen_test_char.c b/rubbos/app/httpd-2.0.64/server/gen_test_char.c deleted file mode 100644 index ef53f9c9..00000000 --- a/rubbos/app/httpd-2.0.64/server/gen_test_char.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef CROSS_COMPILE - -#define apr_isalnum(c) (isalnum(((unsigned char)(c)))) -#define apr_isalpha(c) (isalpha(((unsigned char)(c)))) -#define apr_iscntrl(c) (iscntrl(((unsigned char)(c)))) -#define apr_isprint(c) (isprint(((unsigned char)(c)))) -#include <ctype.h> -#define APR_HAVE_STDIO_H 1 -#define APR_HAVE_STRING_H 1 - -#else - -#include "apr.h" -#include "apr_lib.h" - -#if defined(WIN32) || defined(OS2) -#define NEED_ENHANCED_ESCAPES -#endif - -#endif - -#if APR_HAVE_STDIO_H -#include <stdio.h> -#endif -#if APR_HAVE_STRING_H -#include <string.h> -#endif - -/* A bunch of functions in util.c scan strings looking for certain characters. - * To make that more efficient we encode a lookup table. - */ -#define T_ESCAPE_SHELL_CMD (0x01) -#define T_ESCAPE_PATH_SEGMENT (0x02) -#define T_OS_ESCAPE_PATH (0x04) -#define T_HTTP_TOKEN_STOP (0x08) -#define T_ESCAPE_LOGITEM (0x10) -#define T_ESCAPE_FORENSIC (0x20) - -int main(int argc, char *argv[]) -{ - unsigned c; - unsigned char flags; - - printf("/* this file is automatically generated by gen_test_char, " - "do not edit */\n" - "#define T_ESCAPE_SHELL_CMD (%u)\n" - "#define T_ESCAPE_PATH_SEGMENT (%u)\n" - "#define T_OS_ESCAPE_PATH (%u)\n" - "#define T_HTTP_TOKEN_STOP (%u)\n" - "#define T_ESCAPE_LOGITEM (%u)\n" - "#define T_ESCAPE_FORENSIC (%u)\n" - "\n" - "static const unsigned char test_char_table[256] = {\n" - " 0,", - T_ESCAPE_SHELL_CMD, - T_ESCAPE_PATH_SEGMENT, - T_OS_ESCAPE_PATH, - T_HTTP_TOKEN_STOP, - T_ESCAPE_LOGITEM, - T_ESCAPE_FORENSIC); - - /* we explicitly dealt with NUL above - * in case some strchr() do bogosity with it */ - - for (c = 1; c < 256; ++c) { - flags = 0; - if (c % 20 == 0) - printf("\n "); - - /* escape_shell_cmd */ -#ifdef NEED_ENHANCED_ESCAPES - /* Win32/OS2 have many of the same vulnerable characters - * as Unix sh, plus the carriage return and percent char. - * The proper escaping of these characters varies from unix - * since Win32/OS2 use carets or doubled-double quotes, - * and neither lf nor cr can be escaped. We escape unix - * specific as well, to assure that cross-compiled unix - * applications behave similiarly when invoked on win32/os2. - * - * Rem please keep in-sync with apr's list in win32/filesys.c - */ - if (strchr("&;`'\"|*?~<>^()[]{}$\\\n\r%", c)) { - flags |= T_ESCAPE_SHELL_CMD; - } -#else - if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) { - flags |= T_ESCAPE_SHELL_CMD; - } -#endif - - if (!apr_isalnum(c) && !strchr("$-_.+!*'(),:@&=~", c)) { - flags |= T_ESCAPE_PATH_SEGMENT; - } - - if (!apr_isalnum(c) && !strchr("$-_.+!*'(),:@&=/~", c)) { - flags |= T_OS_ESCAPE_PATH; - } - - /* these are the "tspecials" from RFC2068 */ - if (apr_iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) { - flags |= T_HTTP_TOKEN_STOP; - } - - /* For logging, escape all control characters, - * double quotes (because they delimit the request in the log file) - * backslashes (because we use backslash for escaping) - * and 8-bit chars with the high bit set - */ - if (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c)) { - flags |= T_ESCAPE_LOGITEM; - } - - /* For forensic logging, escape all control characters, top bit set, - * :, | (used as delimiters) and % (used for escaping). - */ - if (!apr_isprint(c) || c == ':' || c == '|' || c == '%' - || apr_iscntrl(c) || !c) { - flags |= T_ESCAPE_FORENSIC; - } - - printf("%u%c", flags, (c < 255) ? ',' : ' '); - } - - printf("\n};\n"); - - return 0; -} diff --git a/rubbos/app/httpd-2.0.64/server/gen_test_char.dsp b/rubbos/app/httpd-2.0.64/server/gen_test_char.dsp deleted file mode 100644 index cc0b943c..00000000 --- a/rubbos/app/httpd-2.0.64/server/gen_test_char.dsp +++ /dev/null @@ -1,94 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gen_test_char" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=gen_test_char - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "gen_test_char.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "gen_test_char.mak" CFG="gen_test_char - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "gen_test_char - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "gen_test_char - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gen_test_char - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\gen_test_char" /FD /c -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\gen_test_char.pdb" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\gen_test_char.pdb" /opt:ref -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "gen_test_char - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\gen_test_char" /FD /c -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_test_char.pdb" /debug /pdbtype:sept -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_test_char.pdb" /debug -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "gen_test_char - Win32 Release" -# Name "gen_test_char - Win32 Debug" -# Begin Source File - -SOURCE=.\gen_test_char.c -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/server/gen_test_char.lo b/rubbos/app/httpd-2.0.64/server/gen_test_char.lo deleted file mode 100644 index b45b02c3..00000000 --- a/rubbos/app/httpd-2.0.64/server/gen_test_char.lo +++ /dev/null @@ -1,12 +0,0 @@ -# gen_test_char.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/gen_test_char.o' - -# Name of the non-PIC object. -non_pic_object='gen_test_char.o' - diff --git a/rubbos/app/httpd-2.0.64/server/gen_test_char.o b/rubbos/app/httpd-2.0.64/server/gen_test_char.o Binary files differdeleted file mode 100644 index 7fb0cbe2..00000000 --- a/rubbos/app/httpd-2.0.64/server/gen_test_char.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/httpd.exp b/rubbos/app/httpd-2.0.64/server/httpd.exp deleted file mode 100644 index 09ac042a..00000000 --- a/rubbos/app/httpd-2.0.64/server/httpd.exp +++ /dev/null @@ -1,421 +0,0 @@ -#! . -* This file was AUTOGENERATED at build time. -* Please do not edit by hand. -ap_set_receive_buffer_size -ap_mpm_run -ap_graceful_stop_signalled -ap_os_create_privileged_process -ap_mpm_query -ap_register_provider -ap_lookup_provider -ap_get_module_config -ap_set_module_config -ap_set_string_slot -ap_set_int_slot -ap_method_is_limited -ap_set_string_slot_lower -ap_set_flag_slot -ap_set_file_slot -ap_set_deprecated -ap_server_root_relative -ap_add_module -ap_remove_module -ap_add_loaded_module -ap_remove_loaded_module -ap_add_named_module -ap_find_module_name -ap_find_linked_module -ap_pcfg_openfile -ap_pcfg_open_custom -ap_cfg_getline -ap_cfg_getc -ap_cfg_closefile -ap_soak_end_container -ap_build_cont_config -ap_build_config -ap_walk_config -ap_check_cmd_context -ap_single_module_configure -ap_setup_prelinked_modules -ap_show_directives -ap_show_modules -ap_show_mpm -ap_read_config -ap_run_rewrite_args -ap_register_hooks -ap_fixup_virtual_hosts -ap_create_request_config -ap_create_per_dir_config -ap_merge_per_dir_configs -ap_create_conn_config -ap_parse_htaccess -ap_init_virtual_host -ap_process_resource_config -ap_process_config_tree -ap_invoke_handler -ap_find_command -ap_find_command_in_modules -ap_set_config_vectors -ap_hook_header_parser -ap_hook_get_header_parser -ap_run_header_parser -ap_hook_pre_config -ap_hook_get_pre_config -ap_run_pre_config -ap_hook_post_config -ap_hook_get_post_config -ap_run_post_config -ap_hook_open_logs -ap_hook_get_open_logs -ap_run_open_logs -ap_hook_child_init -ap_hook_get_child_init -ap_run_child_init -ap_hook_handler -ap_hook_get_handler -ap_run_handler -ap_hook_quick_handler -ap_hook_get_quick_handler -ap_run_quick_handler -ap_hook_optional_fn_retrieve -ap_hook_get_optional_fn_retrieve -ap_run_optional_fn_retrieve -ap_process_connection -ap_flush_conn -ap_lingering_close -ap_hook_create_connection -ap_hook_get_create_connection -ap_run_create_connection -ap_hook_pre_connection -ap_hook_get_pre_connection -ap_run_pre_connection -ap_hook_process_connection -ap_hook_get_process_connection -ap_run_process_connection -ap_bucket_eoc_make -ap_bucket_eoc_create -ap_allow_options -ap_allow_overrides -ap_default_type -ap_document_root -ap_get_remote_host -ap_get_remote_logname -ap_construct_url -ap_get_server_name -ap_get_server_port -ap_get_limit_req_body -ap_get_limit_xml_body -ap_custom_response -ap_is_recursion_limit_exceeded -ap_exists_config_define -ap_core_translate -ap_auth_type -ap_auth_name -ap_satisfies -ap_requires -ap_register_request_note -ap_get_request_note -ap_add_per_dir_conf -ap_add_per_url_conf -ap_add_file_conf -ap_limit_section -ap_hook_get_mgmt_items -ap_hook_get_get_mgmt_items -ap_run_get_mgmt_items -ap_get_server_revision -ap_get_server_version -ap_add_version_component -ap_get_server_built -ap_field_noparam -ap_ht_time -ap_getword -ap_getword_nc -ap_getword_white -ap_getword_white_nc -ap_getword_nulls -ap_getword_nulls_nc -ap_getword_conf -ap_getword_conf_nc -ap_resolve_env -ap_size_list_item -ap_get_list_item -ap_find_list_item -ap_get_token -ap_find_token -ap_find_last_token -ap_is_url -ap_unescape_url -ap_unescape_url_keep2f -ap_no2slash -ap_getparents -ap_escape_path_segment -ap_os_escape_path -ap_escape_html -ap_escape_logitem -ap_escape_errorlog_item -ap_construct_server -ap_escape_shell_cmd -ap_count_dirs -ap_make_dirstr_prefix -ap_make_dirstr_parent -ap_make_full_path -ap_os_is_path_absolute -ap_is_matchexp -ap_strcmp_match -ap_strcasecmp_match -ap_strcasestr -ap_stripprefix -ap_pbase64decode -ap_pbase64encode -ap_pregcomp -ap_pregfree -ap_regexec -ap_regerror -ap_pregsub -ap_content_type_tolower -ap_str_tolower -ap_ind -ap_rind -ap_escape_quotes -ap_is_rdirectory -ap_is_directory -ap_log_assert -ap_psignature -ap_strchr -ap_strchr_c -ap_strrchr -ap_strrchr_c -ap_strstr -ap_strstr_c -ap_open_stderr_log -ap_replace_stderr_log -ap_log_error -ap_log_perror -ap_log_rerror -ap_log_cerror -ap_error_log2stderr -ap_log_pid -ap_read_pid -ap_open_piped_log -ap_close_piped_log -ap_hook_error_log -ap_hook_get_error_log -ap_run_error_log -ap_hook_insert_error_filter -ap_hook_get_insert_error_filter -ap_run_insert_error_filter -ap_get_mime_headers -ap_get_mime_headers_core -ap_finalize_request_protocol -ap_send_error_response -ap_set_content_length -ap_set_keepalive -ap_rationalize_mtime -ap_make_content_type -ap_setup_make_content_type -ap_make_etag -ap_set_etag -ap_set_last_modified -ap_meets_conditions -ap_send_fd -ap_send_mmap -ap_method_register -ap_method_registry_init -ap_make_method_list -ap_copy_method_list -ap_method_list_do -ap_method_list_vdo -ap_method_in_list -ap_method_list_add -ap_method_list_remove -ap_clear_method_list -ap_set_content_type -ap_rputc -ap_rputs -ap_rwrite -ap_rvputs -ap_vrprintf -ap_rprintf -ap_rflush -ap_index_of_response -ap_get_status_line -ap_setup_client_block -ap_should_client_block -ap_get_client_block -ap_discard_request_body -ap_note_auth_failure -ap_note_basic_auth_failure -ap_note_digest_auth_failure -ap_get_basic_auth_pw -ap_parse_uri -ap_getline -ap_rgetline_core -ap_method_number_of -ap_method_name_of -ap_hook_post_read_request -ap_hook_get_post_read_request -ap_run_post_read_request -ap_hook_log_transaction -ap_hook_get_log_transaction -ap_run_log_transaction -ap_hook_http_method -ap_hook_get_http_method -ap_run_http_method -ap_hook_default_port -ap_hook_get_default_port -ap_run_default_port -ap_bucket_error_make -ap_bucket_error_create -ap_byterange_filter -ap_http_header_filter -ap_content_length_filter -ap_old_write_filter -ap_set_sub_req_protocol -ap_finalize_sub_req_protocol -ap_process_request_internal -ap_sub_req_lookup_uri -ap_sub_req_lookup_file -ap_sub_req_lookup_dirent -ap_sub_req_method_uri -ap_sub_req_output_filter -ap_run_sub_req -ap_destroy_sub_req -ap_internal_redirect -ap_internal_redirect_handler -ap_internal_fast_redirect -ap_some_auth_required -ap_is_initial_req -ap_update_mtime -ap_allow_methods -ap_allow_standard_methods -ap_die -ap_hook_create_request -ap_hook_get_create_request -ap_run_create_request -ap_hook_translate_name -ap_hook_get_translate_name -ap_run_translate_name -ap_hook_map_to_storage -ap_hook_get_map_to_storage -ap_run_map_to_storage -ap_hook_check_user_id -ap_hook_get_check_user_id -ap_run_check_user_id -ap_hook_fixups -ap_hook_get_fixups -ap_run_fixups -ap_hook_type_checker -ap_hook_get_type_checker -ap_run_type_checker -ap_hook_access_checker -ap_hook_get_access_checker -ap_run_access_checker -ap_hook_auth_checker -ap_hook_get_auth_checker -ap_run_auth_checker -ap_hook_insert_filter -ap_hook_get_insert_filter -ap_run_insert_filter -ap_location_walk -ap_directory_walk -ap_file_walk -ap_init_vhost_config -ap_fini_vhost_config -ap_vhost_iterate_given_conn -ap_update_vhost_given_ip -ap_update_vhost_from_headers -ap_matches_request_vhost -ap_uname2id -ap_gname2id -ap_exists_scoreboard_image -ap_increment_counts -ap_calc_scoreboard_size -ap_create_sb_handle -find_child_by_pid -ap_update_child_status -ap_update_child_status_from_indexes -ap_get_scoreboard_worker -ap_get_scoreboard_process -ap_get_scoreboard_global -ap_hook_pre_mpm -ap_hook_get_pre_mpm -ap_run_pre_mpm -ap_get_brigade -ap_pass_brigade -ap_register_input_filter -ap_register_output_filter -ap_add_input_filter -ap_add_input_filter_handle -ap_get_input_filter_handle -ap_add_output_filter -ap_add_output_filter_handle -ap_get_output_filter_handle -ap_remove_input_filter -ap_remove_output_filter -ap_save_brigade -ap_filter_flush -ap_fflush -ap_fputstrs -ap_fprintf -ap_md5 -ap_md5_binary -ap_md5contextTo64 -ap_md5digest -ap_create_environment -ap_find_path_info -ap_add_cgi_vars -ap_add_common_vars -ap_scan_script_header_err -ap_scan_script_header_err_brigade -ap_scan_script_header_err_strs -ap_scan_script_header_err_core -ap_explode_recent_localtime -ap_explode_recent_gmt -ap_recent_ctime -ap_recent_rfc822_date -ap_xml_parse_input -ap_basic_http_header -ap_send_http_trace -ap_send_http_options -ap_hook_get_suexec_identity -ap_hook_get_get_suexec_identity -ap_run_get_suexec_identity -unixd_setup_child -unixd_pre_config -unixd_set_user -unixd_set_group -unixd_set_rlimit -unixd_set_proc_mutex_perms -unixd_set_global_mutex_perms -unixd_accept -apu_version -apu_version_string -ap_listeners -ap_top_module -ap_prelinked_modules -ap_preloaded_modules -ap_loaded_modules -ap_bucket_type_eoc -core_module -ap_subreq_core_filter_handle -ap_core_output_filter_handle -ap_content_length_filter_handle -ap_net_time_filter_handle -ap_core_input_filter_handle -ap_server_argv0 -ap_server_root -ap_server_pre_read_config -ap_server_post_read_config -ap_server_config_defines -ap_old_write_func -ap_bucket_type_error -ap_scoreboard_image -ap_scoreboard_fname -ap_extended_status -ap_my_generation -ap_conftree -ap_http_input_filter_handle -ap_http_header_filter_handle -ap_chunk_filter_handle -ap_byterange_filter_handle -unixd_config diff --git a/rubbos/app/httpd-2.0.64/server/libmain.la b/rubbos/app/httpd-2.0.64/server/libmain.la deleted file mode 100644 index 88fb990a..00000000 --- a/rubbos/app/httpd-2.0.64/server/libmain.la +++ /dev/null @@ -1,35 +0,0 @@ -# libmain.la - a libtool library file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='' - -# Names of this library. -library_names='' - -# The name of the static archive. -old_library='libmain.a' - -# Libraries that this one depends upon. -dependency_libs=' -L/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/xml/expat/lib' - -# Version information for libmain. -current= -age= -revision= - -# Is this an already installed library? -installed=no - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='' diff --git a/rubbos/app/httpd-2.0.64/server/listen.c b/rubbos/app/httpd-2.0.64/server/listen.c deleted file mode 100644 index 32bc72a5..00000000 --- a/rubbos/app/httpd-2.0.64/server/listen.c +++ /dev/null @@ -1,494 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_network_io.h" -#include "apr_strings.h" - -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "ap_listen.h" -#include "http_log.h" -#include "mpm.h" -#include "mpm_common.h" - -ap_listen_rec *ap_listeners = NULL; - -#if APR_HAVE_IPV6 -static int default_family = APR_UNSPEC; -#else -static int default_family = APR_INET; -#endif - -static ap_listen_rec *old_listeners; -static int ap_listenbacklog; -static int send_buffer_size; -static int receive_buffer_size; - -/* TODO: make_sock is just begging and screaming for APR abstraction */ -static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) -{ - apr_socket_t *s = server->sd; - int one = 1; -#if APR_HAVE_IPV6 -#ifdef AP_ENABLE_V4_MAPPED - int v6only_setting = 0; -#else - int v6only_setting = 1; -#endif -#endif - apr_status_t stat; - -#ifndef WIN32 - stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one); - if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { - ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, - "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", - server->bind_addr); - apr_socket_close(s); - return stat; - } -#endif - - stat = apr_socket_opt_set(s, APR_SO_KEEPALIVE, one); - if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { - ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, - "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)", - server->bind_addr); - apr_socket_close(s); - return stat; - } - -#if APR_HAVE_IPV6 - if (server->bind_addr->family == APR_INET6) { - stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); - if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { - ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, - "make_sock: for address %pI, apr_socket_opt_set: " - "(IPV6_V6ONLY)", - server->bind_addr); - apr_socket_close(s); - return stat; - } - } -#endif - - /* - * To send data over high bandwidth-delay connections at full - * speed we must force the TCP window to open wide enough to keep the - * pipe full. The default window size on many systems - * is only 4kB. Cross-country WAN connections of 100ms - * at 1Mb/s are not impossible for well connected sites. - * If we assume 100ms cross-country latency, - * a 4kB buffer limits throughput to 40kB/s. - * - * To avoid this problem I've added the SendBufferSize directive - * to allow the web master to configure send buffer size. - * - * The trade-off of larger buffers is that more kernel memory - * is consumed. YMMV, know your customers and your network! - * - * -John Heidemann <johnh@isi.edu> 25-Oct-96 - * - * If no size is specified, use the kernel default. - */ - if (send_buffer_size) { - stat = apr_socket_opt_set(s, APR_SO_SNDBUF, send_buffer_size); - if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { - ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, - "make_sock: failed to set SendBufferSize for " - "address %pI, using default", - server->bind_addr); - /* not a fatal error */ - } - } - if (receive_buffer_size) { - stat = apr_socket_opt_set(s, APR_SO_RCVBUF, receive_buffer_size); - if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { - ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, - "make_sock: failed to set ReceiveBufferSize for " - "address %pI, using default", - server->bind_addr); - /* not a fatal error */ - } - } - -#if APR_TCP_NODELAY_INHERITED - ap_sock_disable_nagle(s); -#endif - - if ((stat = apr_bind(s, server->bind_addr)) != APR_SUCCESS) { - ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, - "make_sock: could not bind to address %pI", - server->bind_addr); - apr_socket_close(s); - return stat; - } - - if ((stat = apr_listen(s, ap_listenbacklog)) != APR_SUCCESS) { - ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, - "make_sock: unable to listen for connections " - "on address %pI", - server->bind_addr); - apr_socket_close(s); - return stat; - } - -#ifdef WIN32 - /* I seriously doubt that this would work on Unix; I have doubts that - * it entirely solves the problem on Win32. However, since setting - * reuseaddr on the listener -prior- to binding the socket has allowed - * us to attach to the same port as an already running instance of - * Apache, or even another web server, we cannot identify that this - * port was exclusively granted to this instance of Apache. - * - * So set reuseaddr, but do not attempt to do so until we have the - * parent listeners successfully bound. - */ - stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one); - if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { - ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, - "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", - server->bind_addr); - apr_socket_close(s); - return stat; - } -#endif - -#if APR_HAS_SO_ACCEPTFILTER -#ifndef ACCEPT_FILTER_NAME -#define ACCEPT_FILTER_NAME "httpready" -#ifdef __FreeBSD_version -#if __FreeBSD_version < 411000 /* httpready was broken before 4.1.1 */ -#undef ACCEPT_FILTER_NAME -#define ACCEPT_FILTER_NAME "dataready" -#endif -#endif -#endif - apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, ""); -#endif - - server->sd = s; - server->active = 1; - -#ifdef MPM_ACCEPT_FUNC - server->accept_func = MPM_ACCEPT_FUNC; -#else - server->accept_func = NULL; -#endif - - return APR_SUCCESS; -} - -static apr_status_t close_listeners_on_exec(void *v) -{ - ap_listen_rec *lr; - - for (lr = ap_listeners; lr; lr = lr->next) { - apr_socket_close(lr->sd); - lr->active = 0; - } - - return APR_SUCCESS; -} - - -static void find_default_family(apr_pool_t *p) -{ -#if APR_HAVE_IPV6 - /* We know the platform supports IPv6, but this particular - * system may not have IPv6 enabled. See if we can get an - * AF_INET6 socket and bind to an ephemeral port. (On most - * systems, getting an AF_INET6 socket is a sufficient test. - * On certain levels of OpenUNIX, getting the socket is - * successful but bind always returns ENETUNREACH.) - */ - if (default_family == APR_UNSPEC) { - apr_status_t sock_rv; - apr_socket_t *tmp_sock; - apr_sockaddr_t *sa; - - if ((sock_rv = apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, p)) - == APR_SUCCESS && - apr_sockaddr_info_get(&sa, NULL, APR_INET6, 0, 0, p) == APR_SUCCESS && - apr_bind(tmp_sock, sa) == APR_SUCCESS) { - default_family = APR_INET6; - } - else { - default_family = APR_INET; - } - if (sock_rv == APR_SUCCESS) { - apr_socket_close(tmp_sock); - } - } -#endif -} - - -static const char *alloc_listener(process_rec *process, char *addr, apr_port_t port) -{ - ap_listen_rec **walk; - ap_listen_rec *new; - apr_status_t status; - apr_port_t oldport; - apr_sockaddr_t *sa; - - if (!addr) { /* don't bind to specific interface */ - find_default_family(process->pool); - switch(default_family) { - case APR_INET: - addr = "0.0.0.0"; - break; - -#if APR_HAVE_IPV6 - case APR_INET6: - addr = "::"; - break; -#endif - - default: - ap_assert(1 != 1); /* should not occur */ - } - } - - /* see if we've got an old listener for this address:port */ - for (walk = &old_listeners; *walk; walk = &(*walk)->next) { - sa = (*walk)->bind_addr; - /* Some listeners are not real so they will not have a bind_addr. */ - if (sa) { - apr_sockaddr_port_get(&oldport, sa); - if (!strcmp(sa->hostname, addr) && port == oldport) { - /* re-use existing record */ - new = *walk; - *walk = new->next; - new->next = ap_listeners; - ap_listeners = new; - return NULL; - } - } - } - - /* this has to survive restarts */ - new = apr_palloc(process->pool, sizeof(ap_listen_rec)); - new->active = 0; - if ((status = apr_sockaddr_info_get(&new->bind_addr, addr, APR_UNSPEC, - port, 0, process->pool)) - != APR_SUCCESS) { - ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, - "alloc_listener: failed to set up sockaddr for %s", - addr); - return "Listen setup failed"; - } - if ((status = apr_socket_create(&new->sd, - new->bind_addr->family, - SOCK_STREAM, process->pool)) - != APR_SUCCESS) { - ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, - "alloc_listener: failed to get a socket for %s", addr); - return "Listen setup failed"; - } - - new->next = ap_listeners; - ap_listeners = new; - return NULL; -} - -static int ap_listen_open(apr_pool_t *pool, apr_port_t port) -{ - ap_listen_rec *lr; - ap_listen_rec *next; - int num_open; - const char *userdata_key = "ap_listen_open"; - void *data; - - /* Don't allocate a default listener. If we need to listen to a - * port, then the user needs to have a Listen directive in their - * config file. - */ - num_open = 0; - for (lr = ap_listeners; lr; lr = lr->next) { - if (lr->active) { - ++num_open; - } - else { - if (make_sock(pool, lr) == APR_SUCCESS) { - ++num_open; - lr->active = 1; - } - else { - /* fatal error */ - return -1; - } - } - } - - /* close the old listeners */ - for (lr = old_listeners; lr; lr = next) { - apr_socket_close(lr->sd); - lr->active = 0; - next = lr->next; - } - old_listeners = NULL; - -#if AP_NONBLOCK_WHEN_MULTI_LISTEN - /* if multiple listening sockets, make them non-blocking so that - * if select()/poll() reports readability for a reset connection that - * is already forgotten about by the time we call accept, we won't - * be hung until another connection arrives on that port - */ - if (ap_listeners && ap_listeners->next) { - for (lr = ap_listeners; lr; lr = lr->next) { - apr_status_t status; - - status = apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, 1); - if (status != APR_SUCCESS) { - ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, status, pool, - "ap_listen_open: unable to make socket non-blocking"); - return -1; - } - } - } -#endif /* AP_NONBLOCK_WHEN_MULTI_LISTEN */ - - /* we come through here on both passes of the open logs phase - * only register the cleanup once... otherwise we try to close - * listening sockets twice when cleaning up prior to exec - */ - apr_pool_userdata_get(&data, userdata_key, pool); - if (!data) { - apr_pool_userdata_set((const void *)1, userdata_key, - apr_pool_cleanup_null, pool); - apr_pool_cleanup_register(pool, NULL, apr_pool_cleanup_null, - close_listeners_on_exec); - } - - return num_open ? 0 : -1; -} - -int ap_setup_listeners(server_rec *s) -{ - ap_listen_rec *lr; - int num_listeners = 0; - - if (ap_listen_open(s->process->pool, s->port)) { - return 0; - } - - for (lr = ap_listeners; lr; lr = lr->next) { - num_listeners++; - } - - return num_listeners; -} - -void ap_listen_pre_config(void) -{ - old_listeners = ap_listeners; - ap_listeners = NULL; - ap_listenbacklog = DEFAULT_LISTENBACKLOG; -} - - -const char *ap_set_listener(cmd_parms *cmd, void *dummy, const char *ips) -{ - char *host, *scope_id; - apr_port_t port; - apr_status_t rv; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - rv = apr_parse_addr_port(&host, &scope_id, &port, ips, cmd->pool); - if (rv != APR_SUCCESS) { - return "Invalid address or port"; - } - - if (host && !strcmp(host, "*")) { - host = NULL; - } - - if (scope_id) { - /* XXX scope id support is useful with link-local IPv6 addresses */ - return "Scope id is not supported"; - } - - if (!port) { - return "Port must be specified"; - } - - return alloc_listener(cmd->server->process, host, port); -} - -const char *ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg) -{ - int b; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - b = atoi(arg); - if (b < 1) { - return "ListenBacklog must be > 0"; - } - - ap_listenbacklog = b; - return NULL; -} - -const char *ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, - const char *arg) -{ - int s = atoi(arg); - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - if (s < 512 && s != 0) { - return "SendBufferSize must be >= 512 bytes, or 0 for system default."; - } - - send_buffer_size = s; - return NULL; -} - -AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, - void *dummy, - const char *arg) -{ - int s = atoi(arg); - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - if (s < 512 && s != 0) { - return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default."; - } - - receive_buffer_size = s; - return NULL; -} diff --git a/rubbos/app/httpd-2.0.64/server/listen.lo b/rubbos/app/httpd-2.0.64/server/listen.lo deleted file mode 100644 index a87ac3b7..00000000 --- a/rubbos/app/httpd-2.0.64/server/listen.lo +++ /dev/null @@ -1,12 +0,0 @@ -# listen.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/listen.o' - -# Name of the non-PIC object. -non_pic_object='listen.o' - diff --git a/rubbos/app/httpd-2.0.64/server/listen.o b/rubbos/app/httpd-2.0.64/server/listen.o Binary files differdeleted file mode 100644 index 3e769684..00000000 --- a/rubbos/app/httpd-2.0.64/server/listen.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/log.c b/rubbos/app/httpd-2.0.64/server/log.c deleted file mode 100644 index 9ab706dd..00000000 --- a/rubbos/app/httpd-2.0.64/server/log.c +++ /dev/null @@ -1,1084 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * http_log.c: Dealing with the logs and errors - * - * Rob McCool - * - */ - -#include "apr.h" -#include "apr_general.h" /* for signal stuff */ -#include "apr_strings.h" -#include "apr_errno.h" -#include "apr_thread_proc.h" -#include "apr_lib.h" -#include "apr_signal.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_STDARG_H -#include <stdarg.h> -#endif -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_log.h" -#include "http_main.h" -#include "util_time.h" -#include "ap_mpm.h" - -#ifndef APR_LARGEFILE -#define APR_LARGEFILE 0 -#endif - -typedef struct { - char *t_name; - int t_val; -} TRANS; - -APR_HOOK_STRUCT( - APR_HOOK_LINK(error_log) -) - -int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL; - -#ifdef HAVE_SYSLOG - -static const TRANS facilities[] = { - {"auth", LOG_AUTH}, -#ifdef LOG_AUTHPRIV - {"authpriv",LOG_AUTHPRIV}, -#endif -#ifdef LOG_CRON - {"cron", LOG_CRON}, -#endif -#ifdef LOG_DAEMON - {"daemon", LOG_DAEMON}, -#endif -#ifdef LOG_FTP - {"ftp", LOG_FTP}, -#endif -#ifdef LOG_KERN - {"kern", LOG_KERN}, -#endif -#ifdef LOG_LPR - {"lpr", LOG_LPR}, -#endif -#ifdef LOG_MAIL - {"mail", LOG_MAIL}, -#endif -#ifdef LOG_NEWS - {"news", LOG_NEWS}, -#endif -#ifdef LOG_SYSLOG - {"syslog", LOG_SYSLOG}, -#endif -#ifdef LOG_USER - {"user", LOG_USER}, -#endif -#ifdef LOG_UUCP - {"uucp", LOG_UUCP}, -#endif -#ifdef LOG_LOCAL0 - {"local0", LOG_LOCAL0}, -#endif -#ifdef LOG_LOCAL1 - {"local1", LOG_LOCAL1}, -#endif -#ifdef LOG_LOCAL2 - {"local2", LOG_LOCAL2}, -#endif -#ifdef LOG_LOCAL3 - {"local3", LOG_LOCAL3}, -#endif -#ifdef LOG_LOCAL4 - {"local4", LOG_LOCAL4}, -#endif -#ifdef LOG_LOCAL5 - {"local5", LOG_LOCAL5}, -#endif -#ifdef LOG_LOCAL6 - {"local6", LOG_LOCAL6}, -#endif -#ifdef LOG_LOCAL7 - {"local7", LOG_LOCAL7}, -#endif - {NULL, -1}, -}; -#endif - -static const TRANS priorities[] = { - {"emerg", APLOG_EMERG}, - {"alert", APLOG_ALERT}, - {"crit", APLOG_CRIT}, - {"error", APLOG_ERR}, - {"warn", APLOG_WARNING}, - {"notice", APLOG_NOTICE}, - {"info", APLOG_INFO}, - {"debug", APLOG_DEBUG}, - {NULL, -1}, -}; - -static apr_pool_t *stderr_pool = NULL; - -static apr_file_t *stderr_log = NULL; - -/* track pipe handles to close in child process */ -typedef struct read_handle_t { - struct read_handle_t *next; - apr_file_t *handle; -} read_handle_t; - -static read_handle_t *read_handles; - -/* clear_handle_list() is called when plog is cleared; at that - * point we need to forget about our old list of pipe read - * handles. We let the plog cleanups close the actual pipes. - */ -static apr_status_t clear_handle_list(void *v) -{ - read_handles = NULL; - return APR_SUCCESS; -} - -/* remember to close this handle in the child process - * - * On Win32 this makes zero sense, because we don't - * take the parent process's child procs. - * If the win32 parent instead passed each and every - * logger write handle from itself down to the child, - * and the parent manages all aspects of keeping the - * reliable pipe log children alive, this would still - * make no sense :) Cripple it on Win32. - */ -static void close_handle_in_child(apr_pool_t *p, apr_file_t *f) -{ -#ifndef WIN32 - read_handle_t *new_handle; - - new_handle = apr_pcalloc(p, sizeof(read_handle_t)); - new_handle->next = read_handles; - new_handle->handle = f; - read_handles = new_handle; -#endif -} - -void ap_logs_child_init(apr_pool_t *p, server_rec *s) -{ - read_handle_t *cur = read_handles; - - while (cur) { - apr_file_close(cur->handle); - cur = cur->next; - } -} - -AP_DECLARE(void) ap_open_stderr_log(apr_pool_t *p) -{ - apr_file_open_stderr(&stderr_log, p); -} - -AP_DECLARE(apr_status_t) ap_replace_stderr_log(apr_pool_t *p, - const char *fname) -{ - apr_file_t *stderr_file; - apr_status_t rc; - char *filename = ap_server_root_relative(p, fname); - if (!filename) { - ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, - APR_EBADPATH, NULL, "Invalid -E error log file %s", - fname); - return APR_EBADPATH; - } - if ((rc = apr_file_open(&stderr_file, filename, - APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE, - APR_OS_DEFAULT, p)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, - "%s: could not open error log file %s.", - ap_server_argv0, fname); - return rc; - } - if (!stderr_pool) { - /* This is safe provided we revert it when we are finished. - * We don't manager the callers pool! - */ - stderr_pool = p; - } - if ((rc = apr_file_open_stderr(&stderr_log, stderr_pool)) - == APR_SUCCESS) { - apr_file_flush(stderr_log); - if ((rc = apr_file_dup2(stderr_log, stderr_file, stderr_pool)) - == APR_SUCCESS) { - apr_file_close(stderr_file); - /* - * You might ponder why stderr_pool should survive? - * The trouble is, stderr_pool may have s_main->error_log, - * so we aren't in a position to destory stderr_pool until - * the next recycle. There's also an apparent bug which - * is not; if some folk decided to call this function before - * the core open error logs hook, this pool won't survive. - * Neither does the stderr logger, so this isn't a problem. - */ - } - } - /* Revert, see above */ - if (stderr_pool == p) - stderr_pool = NULL; - - if (rc != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rc, NULL, - "unable to replace stderr with error log file"); - } - return rc; -} - -static void log_child_errfn(apr_pool_t *pool, apr_status_t err, - const char *description) -{ - ap_log_error(APLOG_MARK, APLOG_ERR, err, NULL, - "%s", description); -} - -/* Create a child process running PROGNAME with a pipe connected to - * the childs stdin. The write-end of the pipe will be placed in - * *FPIN on successful return. If dummy_stderr is non-zero, the - * stderr for the child will be the same as the stdout of the parent. - * Otherwise the child will inherit the stderr from the parent. */ -static int log_child(apr_pool_t *p, const char *progname, - apr_file_t **fpin, int dummy_stderr) -{ - /* Child process code for 'ErrorLog "|..."'; - * may want a common framework for this, since I expect it will - * be common for other foo-loggers to want this sort of thing... - */ - apr_status_t rc; - apr_procattr_t *procattr; - apr_proc_t *procnew; - apr_file_t *outfile, *errfile; - - if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) - && ((rc = apr_procattr_io_set(procattr, - APR_FULL_BLOCK, - APR_NO_PIPE, - APR_NO_PIPE)) == APR_SUCCESS) - && ((rc = apr_procattr_error_check_set(procattr, 1)) == APR_SUCCESS) - && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) - == APR_SUCCESS)) { - char **args; - const char *pname; - - apr_tokenize_to_argv(progname, &args, p); - pname = apr_pstrdup(p, args[0]); - procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew)); - - if ((rc = apr_file_open_stdout(&outfile, p)) == APR_SUCCESS) { - rc = apr_procattr_child_out_set(procattr, outfile, NULL); - if (dummy_stderr) - rc = apr_procattr_child_err_set(procattr, outfile, NULL); - else if ((rc = apr_file_open_stderr(&errfile, p)) == APR_SUCCESS) - rc = apr_procattr_child_err_set(procattr, errfile, NULL); - } - - rc = apr_proc_create(procnew, pname, (const char * const *)args, - NULL, procattr, p); - - if (rc == APR_SUCCESS) { - apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); - (*fpin) = procnew->in; - /* read handle to pipe not kept open, so no need to call - * close_handle_in_child() - */ - } - } - - return rc; -} - -/* Open the error log for the given server_rec. If IS_MAIN is - * non-zero, s is the main server. */ -static int open_error_log(server_rec *s, int is_main, apr_pool_t *p) -{ - const char *fname; - int rc; - - if (*s->error_fname == '|') { - apr_file_t *dummy = NULL; - - /* Spawn a new child logger. If this is the main server_rec, - * the new child must use a dummy stderr since the current - * stderr might be a pipe to the old logger. Otherwise, the - * child inherits the parents stderr. */ - rc = log_child(p, s->error_fname + 1, &dummy, is_main); - if (rc != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, - "Couldn't start ErrorLog process"); - return DONE; - } - - s->error_log = dummy; - } - -#ifdef HAVE_SYSLOG - else if (!strncasecmp(s->error_fname, "syslog", 6)) { - if ((fname = strchr(s->error_fname, ':'))) { - const TRANS *fac; - - fname++; - for (fac = facilities; fac->t_name; fac++) { - if (!strcasecmp(fname, fac->t_name)) { - openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, - fac->t_val); - s->error_log = NULL; - return OK; - } - } - } - else { - openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7); - } - - s->error_log = NULL; - } -#endif - else { - fname = ap_server_root_relative(p, s->error_fname); - if (!fname) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, APR_EBADPATH, NULL, - "%s: Invalid error log path %s.", - ap_server_argv0, s->error_fname); - return DONE; - } - if ((rc = apr_file_open(&s->error_log, fname, - APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE, - APR_OS_DEFAULT, p)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, - "%s: could not open error log file %s.", - ap_server_argv0, fname); - return DONE; - } - } - - return OK; -} - -int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, - apr_pool_t *ptemp, server_rec *s_main) -{ - apr_pool_t *stderr_p; - server_rec *virt, *q; - int replace_stderr; - - - /* Register to throw away the read_handles list when we - * cleanup plog. Upon fork() for the apache children, - * this read_handles list is closed so only the parent - * can relaunch a lost log child. These read handles - * are always closed on exec. - * We won't care what happens to our stderr log child - * between log phases, so we don't mind losing stderr's - * read_handle a little bit early. - */ - apr_pool_cleanup_register(p, NULL, clear_handle_list, - apr_pool_cleanup_null); - - /* HERE we need a stdout log that outlives plog. - * We *presume* the parent of plog is a process - * or global pool which spans server restarts. - * Create our stderr_pool as a child of the plog's - * parent pool. - */ - apr_pool_create(&stderr_p, apr_pool_parent_get(p)); - apr_pool_tag(stderr_p, "stderr_pool"); - - if (open_error_log(s_main, 1, stderr_p) != OK) { - return DONE; - } - - replace_stderr = 1; - if (s_main->error_log) { - apr_status_t rv; - - /* Replace existing stderr with new log. */ - apr_file_flush(s_main->error_log); - rv = apr_file_dup2(stderr_log, s_main->error_log, stderr_p); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s_main, - "unable to replace stderr with error_log"); - } - else { - /* We are done with stderr_pool, close it, killing - * the previous generation's stderr logger - */ - if (stderr_pool) - apr_pool_destroy(stderr_pool); - stderr_pool = stderr_p; - replace_stderr = 0; - /* - * Now that we have dup'ed s_main->error_log to stderr_log - * close it and set s_main->error_log to stderr_log. This avoids - * this fd being inherited by the next piped logger who would - * keep open the writing end of the pipe that this one uses - * as stdin. This in turn would prevent the piped logger from - * exiting. - */ - apr_file_close(s_main->error_log); - s_main->error_log = stderr_log; - } - } - /* note that stderr may still need to be replaced with something - * because it points to the old error log, or back to the tty - * of the submitter. - * XXX: This is BS - /dev/null is non-portable - */ - if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) { - ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s_main, - "unable to replace stderr with /dev/null"); - } - - for (virt = s_main->next; virt; virt = virt->next) { - if (virt->error_fname) { - for (q=s_main; q != virt; q = q->next) { - if (q->error_fname != NULL - && strcmp(q->error_fname, virt->error_fname) == 0) { - break; - } - } - - if (q == virt) { - if (open_error_log(virt, 0, p) != OK) { - return DONE; - } - } - else { - virt->error_log = q->error_log; - } - } - else { - virt->error_log = s_main->error_log; - } - } - return OK; -} - -AP_DECLARE(void) ap_error_log2stderr(server_rec *s) { - apr_file_t *errfile = NULL; - - apr_file_open_stderr(&errfile, s->process->pool); - if (s->error_log != NULL) { - apr_file_dup2(s->error_log, errfile, s->process->pool); - } -} - -static void log_error_core(const char *file, int line, int level, - apr_status_t status, const server_rec *s, - const conn_rec *c, - const request_rec *r, apr_pool_t *pool, - const char *fmt, va_list args) -{ - char errstr[MAX_STRING_LEN]; -#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED - char scratch[MAX_STRING_LEN]; -#endif - apr_size_t len, errstrlen; - apr_file_t *logf = NULL; - const char *referer; - int level_and_mask = level & APLOG_LEVELMASK; - - if (r && r->connection) { - c = r->connection; - } - - if (s == NULL) { - /* - * If we are doing stderr logging (startup), don't log messages that are - * above the default server log level unless it is a startup/shutdown - * notice - */ - if ((level_and_mask != APLOG_NOTICE) - && (level_and_mask > ap_default_loglevel)) { - return; - } - - logf = stderr_log; - } - else if (s->error_log) { - /* - * If we are doing normal logging, don't log messages that are - * above the server log level unless it is a startup/shutdown notice - */ - if ((level_and_mask != APLOG_NOTICE) - && (level_and_mask > s->loglevel)) { - return; - } - - logf = s->error_log; - } -#ifdef TPF - else if (tpf_child) { - /* - * If we are doing normal logging, don't log messages that are - * above the server log level unless it is a startup/shutdown notice - */ - if ((level_and_mask != APLOG_NOTICE) - && (level_and_mask > s->loglevel)) { - return; - } - - logf = stderr; - } -#endif /* TPF */ - else { - /* - * If we are doing syslog logging, don't log messages that are - * above the server log level (including a startup/shutdown notice) - */ - if (level_and_mask > s->loglevel) { - return; - } - } - - if (logf && ((level & APLOG_STARTUP) != APLOG_STARTUP)) { - errstr[0] = '['; - ap_recent_ctime(errstr + 1, apr_time_now()); - errstr[1 + APR_CTIME_LEN - 1] = ']'; - errstr[1 + APR_CTIME_LEN ] = ' '; - len = 1 + APR_CTIME_LEN + 1; - } else { - len = 0; - } - - if ((level & APLOG_STARTUP) != APLOG_STARTUP) { - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "[%s] ", priorities[level_and_mask].t_name); - } - -#ifndef TPF - if (file && level_and_mask == APLOG_DEBUG) { -#if defined(_OSD_POSIX) || defined(WIN32) || defined(__MVS__) - char tmp[256]; - char *e = strrchr(file, '/'); -#ifdef WIN32 - if (!e) { - e = strrchr(file, '\\'); - } -#endif - - /* In OSD/POSIX, the compiler returns for __FILE__ - * a string like: __FILE__="*POSIX(/usr/include/stdio.h)" - * (it even returns an absolute path for sources in - * the current directory). Here we try to strip this - * down to the basename. - */ - if (e != NULL && e[1] != '\0') { - apr_snprintf(tmp, sizeof(tmp), "%s", &e[1]); - e = &tmp[strlen(tmp)-1]; - if (*e == ')') { - *e = '\0'; - } - file = tmp; - } -#else /* _OSD_POSIX || WIN32 */ - const char *p; - /* On Unix, __FILE__ may be an absolute path in a - * VPATH build. */ - if (file[0] == '/' && (p = ap_strrchr_c(file, '/')) != NULL) { - file = p + 1; - } -#endif /*_OSD_POSIX || WIN32 */ - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "%s(%d): ", file, line); - } -#endif /* TPF */ - - if (c) { - /* XXX: TODO: add a method of selecting whether logged client - * addresses are in dotted quad or resolved form... dotted - * quad is the most secure, which is why I'm implementing it - * first. -djg - */ - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "[client %s] ", c->remote_ip); - } - if (status != 0) { - if (status < APR_OS_START_EAIERR) { - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "(%d)", status); - } - else if (status < APR_OS_START_SYSERR) { - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "(EAI %d)", status - APR_OS_START_EAIERR); - } - else if (status < 100000 + APR_OS_START_SYSERR) { - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "(OS %d)", status - APR_OS_START_SYSERR); - } - else { - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - "(os 0x%08x)", status - APR_OS_START_SYSERR); - } - apr_strerror(status, errstr + len, MAX_STRING_LEN - len); - len += strlen(errstr + len); - if (MAX_STRING_LEN - len > 2) { - errstr[len++] = ':'; - errstr[len++] = ' '; - errstr[len] = '\0'; - } - } - - errstrlen = len; -#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED - if (apr_vsnprintf(scratch, MAX_STRING_LEN - len, fmt, args)) { - len += ap_escape_errorlog_item(errstr + len, scratch, - MAX_STRING_LEN - len); - } -#else - len += apr_vsnprintf(errstr + len, MAX_STRING_LEN - len, fmt, args); -#endif - - if ( r && (referer = apr_table_get(r->headers_in, "Referer")) -#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED - && ap_escape_errorlog_item(scratch, referer, MAX_STRING_LEN - len) -#endif - ) { - len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, - ", referer: %s", -#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED - scratch -#else - referer -#endif - ); - } - - /* NULL if we are logging to syslog */ - if (logf) { - /* Truncate for the terminator (as apr_snprintf does) */ - if (len > MAX_STRING_LEN - sizeof(APR_EOL_STR)) { - len = MAX_STRING_LEN - sizeof(APR_EOL_STR); - } - strcpy(errstr + len, APR_EOL_STR); - apr_file_puts(errstr, logf); - apr_file_flush(logf); - } -#ifdef HAVE_SYSLOG - else { - syslog(level_and_mask, "%s", errstr); - } -#endif - - ap_run_error_log(file, line, level, status, s, r, pool, errstr + errstrlen); -} - -AP_DECLARE(void) ap_log_error(const char *file, int line, int level, - apr_status_t status, const server_rec *s, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - log_error_core(file, line, level, status, s, NULL, NULL, NULL, fmt, args); - va_end(args); -} - -AP_DECLARE(void) ap_log_perror(const char *file, int line, int level, - apr_status_t status, apr_pool_t *p, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - log_error_core(file, line, level, status, NULL, NULL, NULL, p, fmt, args); - va_end(args); -} - -AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level, - apr_status_t status, const request_rec *r, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - log_error_core(file, line, level, status, r->server, NULL, r, NULL, fmt, - args); - - /* - * IF APLOG_TOCLIENT is set, - * AND the error level is 'warning' or more severe, - * AND there isn't already error text associated with this request, - * THEN make the message text available to ErrorDocument and - * other error processors. - */ - va_end(args); - va_start(args,fmt); - if ((level & APLOG_TOCLIENT) - && ((level & APLOG_LEVELMASK) <= APLOG_WARNING) - && (apr_table_get(r->notes, "error-notes") == NULL)) { - apr_table_setn(r->notes, "error-notes", - ap_escape_html(r->pool, apr_pvsprintf(r->pool, fmt, - args))); - } - va_end(args); -} - -AP_DECLARE(void) ap_log_cerror(const char *file, int line, int level, - apr_status_t status, const conn_rec *c, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - log_error_core(file, line, level, status, c->base_server, c, NULL, NULL, - fmt, args); - va_end(args); -} - -AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename) -{ - apr_file_t *pid_file = NULL; - apr_finfo_t finfo; - static pid_t saved_pid = -1; - pid_t mypid; - apr_status_t rv; - const char *fname; - - if (!filename) { - return; - } - - fname = ap_server_root_relative(p, filename); - if (!fname) { - ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH, - NULL, "Invalid PID file path %s, ignoring.", filename); - return; - } - - mypid = getpid(); - if (mypid != saved_pid - && apr_stat(&finfo, fname, APR_FINFO_MTIME, p) == APR_SUCCESS) { - /* AP_SIG_GRACEFUL and HUP call this on each restart. - * Only warn on first time through for this pid. - * - * XXX: Could just write first time through too, although - * that may screw up scripts written to do something - * based on the last modification time of the pid file. - */ - ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p, - apr_psprintf(p, "pid file %s overwritten -- Unclean " - "shutdown of previous Apache run?", - fname)); - } - - if ((rv = apr_file_open(&pid_file, fname, - APR_WRITE | APR_CREATE | APR_TRUNCATE, - APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, p)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "could not create %s", fname); - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "%s: could not log pid to file %s", - ap_server_argv0, fname); - exit(1); - } - apr_file_printf(pid_file, "%ld" APR_EOL_STR, (long)mypid); - apr_file_close(pid_file); - saved_pid = mypid; -} - -AP_DECLARE(apr_status_t) ap_read_pid(apr_pool_t *p, const char *filename, - pid_t *mypid) -{ - const apr_size_t BUFFER_SIZE = sizeof(long) * 3 + 2; /* see apr_ltoa */ - apr_file_t *pid_file = NULL; - apr_status_t rv; - const char *fname; - char *buf, *endptr; - apr_size_t bytes_read; - - if (!filename) { - return APR_EGENERAL; - } - - fname = ap_server_root_relative(p, filename); - if (!fname) { - ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH, - NULL, "Invalid PID file path %s, ignoring.", filename); - return APR_EGENERAL; - } - - rv = apr_file_open(&pid_file, fname, APR_READ, APR_OS_DEFAULT, p); - if (rv != APR_SUCCESS) { - return rv; - } - - /* Ensure null-termination, so that strtol doesn't go crazy. */ - buf = apr_palloc(p, BUFFER_SIZE); - buf[BUFFER_SIZE - 1] = '\0'; - - rv = apr_file_read_full(pid_file, buf, BUFFER_SIZE - 1, &bytes_read); - if (rv != APR_SUCCESS && rv != APR_EOF) { - return rv; - } - - /* If we fill the buffer, we're probably reading a corrupt pid file. - * To be nice, let's also ensure the first char is a digit. */ - if (bytes_read == BUFFER_SIZE - 1 || !apr_isdigit(*buf)) { - return APR_EGENERAL; - } - - *mypid = strtol(buf, &endptr, 10); - - apr_file_close(pid_file); - return APR_SUCCESS; -} - -AP_DECLARE(void) ap_log_assert(const char *szExp, const char *szFile, - int nLine) -{ - char time_str[APR_CTIME_LEN]; - - apr_ctime(time_str, apr_time_now()); - ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, - "[%s] file %s, line %d, assertion \"%s\" failed", - time_str, szFile, nLine, szExp); -#if defined(WIN32) - DebugBreak(); -#else - /* unix assert does an abort leading to a core dump */ - abort(); -#endif -} - -/* piped log support */ - -#ifdef AP_HAVE_RELIABLE_PIPED_LOGS -/* forward declaration */ -static void piped_log_maintenance(int reason, void *data, apr_wait_t status); - -/* Spawn the piped logger process pl->program. */ -static apr_status_t piped_log_spawn(piped_log *pl) -{ - apr_procattr_t *procattr; - apr_proc_t *procnew = NULL; - apr_status_t status; - - if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) || - ((status = apr_procattr_child_in_set(procattr, - ap_piped_log_read_fd(pl), - ap_piped_log_write_fd(pl))) - != APR_SUCCESS) || - ((status = apr_procattr_child_errfn_set(procattr, log_child_errfn)) - != APR_SUCCESS) || - ((status = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS)) { - char buf[120]; - /* Something bad happened, give up and go away. */ - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "piped_log_spawn: unable to setup child process '%s': %s", - pl->program, apr_strerror(status, buf, sizeof(buf))); - } - else { - char **args; - const char *pname; - apr_file_t *outfile, *errfile; - - if ((status = apr_file_open_stdout(&outfile, pl->p)) == APR_SUCCESS) - status = apr_procattr_child_out_set(procattr, outfile, NULL); - if ((status = apr_file_open_stderr(&errfile, pl->p)) == APR_SUCCESS) - status = apr_procattr_child_err_set(procattr, errfile, NULL); - - apr_tokenize_to_argv(pl->program, &args, pl->p); - pname = apr_pstrdup(pl->p, args[0]); - procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t)); - status = apr_proc_create(procnew, pname, (const char * const *) args, - NULL, procattr, pl->p); - - if (status == APR_SUCCESS) { - pl->pid = procnew; - /* procnew->in was dup2'd from ap_piped_log_write_fd(pl); - * since the original fd is still valid, close the copy to - * avoid a leak. */ - apr_file_close(procnew->in); - procnew->in = NULL; - apr_proc_other_child_register(procnew, piped_log_maintenance, pl, - ap_piped_log_write_fd(pl), pl->p); - close_handle_in_child(pl->p, ap_piped_log_read_fd(pl)); - } - else { - char buf[120]; - /* Something bad happened, give up and go away. */ - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "unable to start piped log program '%s': %s", - pl->program, apr_strerror(status, buf, sizeof(buf))); - } - } - - return status; -} - - -static void piped_log_maintenance(int reason, void *data, apr_wait_t status) -{ - piped_log *pl = data; - apr_status_t stats; - int mpm_state; - - switch (reason) { - case APR_OC_REASON_DEATH: - case APR_OC_REASON_LOST: - pl->pid = NULL; /* in case we don't get it going again, this - * tells other logic not to try to kill it - */ - apr_proc_other_child_unregister(pl); - stats = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state); - if (stats != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "can't query MPM state; not restarting " - "piped log program '%s'", - pl->program); - } - else if (mpm_state != AP_MPMQ_STOPPING) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "piped log program '%s' failed unexpectedly", - pl->program); - if ((stats = piped_log_spawn(pl)) != APR_SUCCESS) { - /* what can we do? This could be the error log we're having - * problems opening up... */ - char buf[120]; - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "piped_log_maintenance: unable to respawn '%s': %s", - pl->program, apr_strerror(stats, buf, sizeof(buf))); - } - } - break; - - case APR_OC_REASON_UNWRITABLE: - /* We should not kill off the pipe here, since it may only be full. - * If it really is locked, we should kill it off manually. */ - break; - - case APR_OC_REASON_RESTART: - if (pl->pid != NULL) { - apr_proc_kill(pl->pid, SIGTERM); - pl->pid = NULL; - } - break; - - case APR_OC_REASON_UNREGISTER: - break; - } -} - - -static apr_status_t piped_log_cleanup_for_exec(void *data) -{ - piped_log *pl = data; - - apr_file_close(ap_piped_log_read_fd(pl)); - apr_file_close(ap_piped_log_write_fd(pl)); - return APR_SUCCESS; -} - - -static apr_status_t piped_log_cleanup(void *data) -{ - piped_log *pl = data; - - if (pl->pid != NULL) { - apr_proc_kill(pl->pid, SIGTERM); - } - return piped_log_cleanup_for_exec(data); -} - - -AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) -{ - piped_log *pl; - - pl = apr_palloc(p, sizeof (*pl)); - pl->p = p; - pl->program = apr_pstrdup(p, program); - pl->pid = NULL; - if (apr_file_pipe_create(&ap_piped_log_read_fd(pl), - &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) { - return NULL; - } - apr_pool_cleanup_register(p, pl, piped_log_cleanup, - piped_log_cleanup_for_exec); - if (piped_log_spawn(pl) != APR_SUCCESS) { - apr_pool_cleanup_kill(p, pl, piped_log_cleanup); - apr_file_close(ap_piped_log_read_fd(pl)); - apr_file_close(ap_piped_log_write_fd(pl)); - return NULL; - } - return pl; -} - -#else /* !AP_HAVE_RELIABLE_PIPED_LOGS */ - -static apr_status_t piped_log_cleanup(void *data) -{ - piped_log *pl = data; - - apr_file_close(ap_piped_log_write_fd(pl)); - return APR_SUCCESS; -} - -AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) -{ - piped_log *pl; - apr_file_t *dummy = NULL; - int rc; - - rc = log_child(p, program, &dummy, 0); - if (rc != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, - "Couldn't start piped log process"); - return NULL; - } - - pl = apr_palloc(p, sizeof (*pl)); - pl->p = p; - ap_piped_log_read_fd(pl) = NULL; - ap_piped_log_write_fd(pl) = dummy; - apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup); - - return pl; -} - -#endif - -AP_DECLARE(void) ap_close_piped_log(piped_log *pl) -{ - apr_pool_cleanup_run(pl->p, pl, piped_log_cleanup); -} - -AP_IMPLEMENT_HOOK_VOID(error_log, - (const char *file, int line, int level, - apr_status_t status, const server_rec *s, - const request_rec *r, apr_pool_t *pool, - const char *errstr), (file, line, level, - status, s, r, pool, errstr)) - diff --git a/rubbos/app/httpd-2.0.64/server/log.lo b/rubbos/app/httpd-2.0.64/server/log.lo deleted file mode 100644 index efbcc123..00000000 --- a/rubbos/app/httpd-2.0.64/server/log.lo +++ /dev/null @@ -1,12 +0,0 @@ -# log.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/log.o' - -# Name of the non-PIC object. -non_pic_object='log.o' - diff --git a/rubbos/app/httpd-2.0.64/server/log.o b/rubbos/app/httpd-2.0.64/server/log.o Binary files differdeleted file mode 100644 index d5f2ee13..00000000 --- a/rubbos/app/httpd-2.0.64/server/log.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/main.c b/rubbos/app/httpd-2.0.64/server/main.c deleted file mode 100644 index aa356418..00000000 --- a/rubbos/app/httpd-2.0.64/server/main.c +++ /dev/null @@ -1,683 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_getopt.h" -#include "apr_general.h" -#include "apr_lib.h" -#include "apr_md5.h" -#include "apr_time.h" -#include "apr_version.h" -#include "apu_version.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" -#include "http_vhost.h" -#include "apr_uri.h" -#include "util_ebcdic.h" -#include "ap_mpm.h" -#include "mpm_common.h" - -/* WARNING: Win32 binds http_main.c dynamically to the server. Please place - * extern functions and global data in another appropriate module. - * - * Most significant main() global data can be found in http_config.c - */ - -/* XXX - We should be able to grab the per-MPM settings here too */ -static void show_compile_settings(void) -{ - printf("Server version: %s\n", ap_get_server_version()); - printf("Server built: %s\n", ap_get_server_built()); - printf("Server's Module Magic Number: %u:%u\n", - MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR); - printf("Server loaded: APR %s, APR-UTIL %s\n", - apr_version_string(), apu_version_string()); - printf("Compiled using: APR %s, APR-UTIL %s\n", - APR_VERSION_STRING, APU_VERSION_STRING); - /* sizeof(foo) is long on some platforms so we might as well - * make it long everywhere to keep the printf format - * consistent - */ - printf("Architecture: %ld-bit\n", 8 * (long)sizeof(void *)); - printf("Server compiled with....\n"); -#ifdef BIG_SECURITY_HOLE - printf(" -D BIG_SECURITY_HOLE\n"); -#endif - -#ifdef SECURITY_HOLE_PASS_AUTHORIZATION - printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n"); -#endif - -#ifdef APACHE_MPM_DIR - printf(" -D APACHE_MPM_DIR=\"%s\"\n", APACHE_MPM_DIR); -#endif - -#ifdef HAVE_SHMGET - printf(" -D HAVE_SHMGET\n"); -#endif - -#if APR_FILE_BASED_SHM - printf(" -D APR_FILE_BASED_SHM\n"); -#endif - -#if APR_HAS_SENDFILE - printf(" -D APR_HAS_SENDFILE\n"); -#endif - -#if APR_HAS_MMAP - printf(" -D APR_HAS_MMAP\n"); -#endif - -#ifdef NO_WRITEV - printf(" -D NO_WRITEV\n"); -#endif - -#ifdef NO_LINGCLOSE - printf(" -D NO_LINGCLOSE\n"); -#endif - -#if APR_HAVE_IPV6 - printf(" -D APR_HAVE_IPV6 (IPv4-mapped addresses "); -#ifdef AP_ENABLE_V4_MAPPED - printf("enabled)\n"); -#else - printf("disabled)\n"); -#endif -#endif - -#if APR_USE_FLOCK_SERIALIZE - printf(" -D APR_USE_FLOCK_SERIALIZE\n"); -#endif - -#if APR_USE_SYSVSEM_SERIALIZE - printf(" -D APR_USE_SYSVSEM_SERIALIZE\n"); -#endif - -#if APR_USE_POSIXSEM_SERIALIZE - printf(" -D APR_USE_POSIXSEM_SERIALIZE\n"); -#endif - -#if APR_USE_FCNTL_SERIALIZE - printf(" -D APR_USE_FCNTL_SERIALIZE\n"); -#endif - -#if APR_USE_PROC_PTHREAD_SERIALIZE - printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n"); -#endif - -#if APR_USE_PTHREAD_SERIALIZE - printf(" -D APR_USE_PTHREAD_SERIALIZE\n"); -#endif - -#if APR_PROCESS_LOCK_IS_GLOBAL - printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n"); -#endif - -#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT - printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n"); -#endif - -#if APR_HAS_OTHER_CHILD - printf(" -D APR_HAS_OTHER_CHILD\n"); -#endif - -#ifdef AP_HAVE_RELIABLE_PIPED_LOGS - printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n"); -#endif - -#ifdef BUFFERED_LOGS - printf(" -D BUFFERED_LOGS\n"); -#ifdef PIPE_BUF - printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF); -#endif -#endif - -#if APR_CHARSET_EBCDIC - printf(" -D APR_CHARSET_EBCDIC\n"); -#endif - -#ifdef APACHE_XLATE - printf(" -D APACHE_XLATE\n"); -#endif - -#ifdef NEED_HASHBANG_EMUL - printf(" -D NEED_HASHBANG_EMUL\n"); -#endif - -#ifdef SHARED_CORE - printf(" -D SHARED_CORE\n"); -#endif - -/* This list displays the compiled in default paths: */ -#ifdef HTTPD_ROOT - printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n"); -#endif - -#ifdef SUEXEC_BIN - printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n"); -#endif - -#if defined(SHARED_CORE) && defined(SHARED_CORE_DIR) - printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n"); -#endif - -#ifdef DEFAULT_PIDLOG - printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n"); -#endif - -#ifdef DEFAULT_SCOREBOARD - printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n"); -#endif - -#ifdef DEFAULT_LOCKFILE - printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n"); -#endif - -#ifdef DEFAULT_ERRORLOG - printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n"); -#endif - -#ifdef AP_TYPES_CONFIG_FILE - printf(" -D AP_TYPES_CONFIG_FILE=\"" AP_TYPES_CONFIG_FILE "\"\n"); -#endif - -#ifdef SERVER_CONFIG_FILE - printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n"); -#endif -} - -static void destroy_and_exit_process(process_rec *process, - int process_exit_value) -{ - apr_pool_destroy(process->pool); /* and destroy all descendent pools */ - apr_terminate(); - exit(process_exit_value); -} - -static process_rec *init_process(int *argc, const char * const * *argv) -{ - process_rec *process; - apr_pool_t *cntx; - apr_status_t stat; - const char *failed = "apr_app_initialize()"; - - stat = apr_app_initialize(argc, argv, NULL); - if (stat == APR_SUCCESS) { - failed = "apr_pool_create()"; - stat = apr_pool_create(&cntx, NULL); - } - - if (stat != APR_SUCCESS) { - /* For all intents and purposes, this is impossibly unlikely, - * but APR doesn't exist yet, we can't use it for reporting - * these earliest two failures; - */ - char ctimebuff[APR_CTIME_LEN]; - apr_ctime(ctimebuff, apr_time_now()); - fprintf(stderr, "[%s] [crit] (%d) %s: %s failed " - "to initial context, exiting\n", - ctimebuff, stat, (*argv)[0], failed); - apr_terminate(); - exit(1); - } - - apr_pool_tag(cntx, "process"); - ap_open_stderr_log(cntx); - - /* Now we have initialized apr and our logger, no more - * exceptional error reporting required for the lifetime - * of this server process. - */ - - process = apr_palloc(cntx, sizeof(process_rec)); - process->pool = cntx; - - apr_pool_create(&process->pconf, process->pool); - apr_pool_tag(process->pconf, "pconf"); - process->argc = *argc; - process->argv = *argv; - process->short_name = apr_filepath_name_get((*argv)[0]); - return process; -} - -static void usage(process_rec *process) -{ - const char *bin = process->argv[0]; - char pad[MAX_STRING_LEN]; - unsigned i; - - for (i = 0; i < strlen(bin); i++) { - pad[i] = ' '; - } - - pad[i] = '\0'; - -#ifdef SHARED_CORE - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL , - "Usage: %s [-R directory] [-D name] [-d directory] [-f file]", - bin); -#else - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Usage: %s [-D name] [-d directory] [-f file]", bin); -#endif - - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-C \"directive\"] [-c \"directive\"]", pad); - -#ifdef WIN32 - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-w] [-k start|restart|stop|shutdown]", pad); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-k install|config|uninstall] [-n service_name]", - pad); -#endif -#ifdef AP_MPM_WANT_SIGNAL_SERVER - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-k start|restart|graceful|stop]", - pad); -#endif - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-v] [-V] [-h] [-l] [-L] [-t] [-S]", pad); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Options:"); - -#ifdef SHARED_CORE - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -R directory : specify an alternate location for " - "shared object files"); -#endif - - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -D name : define a name for use in " - "<IfDefine name> directives"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -d directory : specify an alternate initial " - "ServerRoot"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -f file : specify an alternate ServerConfigFile"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -C \"directive\" : process directive before reading " - "config files"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -c \"directive\" : process directive after reading " - "config files"); - -#ifdef NETWARE - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -n name : set screen name"); -#endif -#ifdef WIN32 - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -n name : set service name and use its " - "ServerConfigFile"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -k start : tell Apache to start"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -k restart : tell running Apache to do a graceful " - "restart"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -k stop|shutdown : tell running Apache to shutdown"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -k install : install an Apache service"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -k config : change startup Options of an Apache " - "service"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -k uninstall : uninstall an Apache service"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -w : hold open the console window on error"); -#endif - - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -e level : show startup errors of level " - "(see LogLevel)"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -E file : log startup errors to file"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -v : show version number"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -V : show compile settings"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -h : list available command line options " - "(this page)"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -l : list compiled in modules"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -L : list available configuration " - "directives"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -t -D DUMP_VHOSTS : show parsed settings (currently only " - "vhost settings)"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -S : a synonym for -t -D DUMP_VHOSTS"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " -t : run syntax check for config files"); - - destroy_and_exit_process(process, 1); -} - -int main(int argc, const char * const argv[]) -{ - char c; - int configtestonly = 0; - const char *confname = SERVER_CONFIG_FILE; - const char *def_server_root = HTTPD_ROOT; - const char *temp_error_log = NULL; - process_rec *process; - server_rec *server_conf; - apr_pool_t *pglobal; - apr_pool_t *pconf; - apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */ - apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */ - apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */ - apr_getopt_t *opt; - apr_status_t rv; - module **mod; - const char *optarg; - APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server; - - AP_MONCONTROL(0); /* turn off profiling of startup */ - - process = init_process(&argc, &argv); - pglobal = process->pool; - pconf = process->pconf; - ap_server_argv0 = process->short_name; - -#if APR_CHARSET_EBCDIC - if (ap_init_ebcdic(pglobal) != APR_SUCCESS) { - destroy_and_exit_process(process, 1); - } -#endif - - apr_pool_create(&pcommands, pglobal); - apr_pool_tag(pcommands, "pcommands"); - ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *)); - ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *)); - ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *)); - - ap_setup_prelinked_modules(process); - - ap_run_rewrite_args(process); - - /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM - * to safely pass on our args from its rewrite_args() handler. - */ - apr_getopt_init(&opt, pcommands, process->argc, process->argv); - - while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg)) - == APR_SUCCESS) { - char **new; - - switch (c) { - case 'c': - new = (char **)apr_array_push(ap_server_post_read_config); - *new = apr_pstrdup(pcommands, optarg); - break; - - case 'C': - new = (char **)apr_array_push(ap_server_pre_read_config); - *new = apr_pstrdup(pcommands, optarg); - break; - - case 'd': - def_server_root = optarg; - break; - - case 'D': - new = (char **)apr_array_push(ap_server_config_defines); - *new = apr_pstrdup(pcommands, optarg); - break; - - case 'e': - if (strcasecmp(optarg, "emerg") == 0) { - ap_default_loglevel = APLOG_EMERG; - } - else if (strcasecmp(optarg, "alert") == 0) { - ap_default_loglevel = APLOG_ALERT; - } - else if (strcasecmp(optarg, "crit") == 0) { - ap_default_loglevel = APLOG_CRIT; - } - else if (strncasecmp(optarg, "err", 3) == 0) { - ap_default_loglevel = APLOG_ERR; - } - else if (strncasecmp(optarg, "warn", 4) == 0) { - ap_default_loglevel = APLOG_WARNING; - } - else if (strcasecmp(optarg, "notice") == 0) { - ap_default_loglevel = APLOG_NOTICE; - } - else if (strcasecmp(optarg, "info") == 0) { - ap_default_loglevel = APLOG_INFO; - } - else if (strcasecmp(optarg, "debug") == 0) { - ap_default_loglevel = APLOG_DEBUG; - } - else { - usage(process); - } - break; - - case 'E': - temp_error_log = apr_pstrdup(process->pool, optarg); - break; - - case 'X': - new = (char **)apr_array_push(ap_server_config_defines); - *new = "DEBUG"; - break; - - case 'f': - confname = optarg; - break; - - case 'v': - printf("Server version: %s\n", ap_get_server_version()); - printf("Server built: %s\n", ap_get_server_built()); - destroy_and_exit_process(process, 0); - - case 'V': - show_compile_settings(); - destroy_and_exit_process(process, 0); - - case 'l': - ap_show_modules(); - destroy_and_exit_process(process, 0); - - case 'L': - ap_show_directives(); - destroy_and_exit_process(process, 0); - - case 't': - configtestonly = 1; - break; - - case 'S': - configtestonly = 1; - new = (char **)apr_array_push(ap_server_config_defines); - *new = "DUMP_VHOSTS"; - break; - - case 'h': - case '?': - usage(process); - } - } - - /* bad cmdline option? then we die */ - if (rv != APR_EOF || opt->ind < opt->argc) { - usage(process); - } - - apr_pool_create(&plog, pglobal); - apr_pool_tag(plog, "plog"); - apr_pool_create(&ptemp, pconf); - apr_pool_tag(ptemp, "ptemp"); - - /* Note that we preflight the config file once - * before reading it _again_ in the main loop. - * This allows things, log files configuration - * for example, to settle down. - */ - - ap_server_root = def_server_root; - if (temp_error_log) { - ap_replace_stderr_log(process->pool, temp_error_log); - } - server_conf = ap_read_config(process, ptemp, confname, &ap_conftree); - if (ap_run_pre_config(pconf, plog, ptemp) != OK) { - ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0, - NULL, "Pre-configuration failed"); - destroy_and_exit_process(process, 1); - } - - ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp); - ap_fixup_virtual_hosts(pconf, server_conf); - ap_fini_vhost_config(pconf, server_conf); - apr_hook_sort_all(); - if (configtestonly) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK"); - destroy_and_exit_process(process, 0); - } - - signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server); - if (signal_server) { - int exit_status; - - if (signal_server(&exit_status, pconf) != 0) { - destroy_and_exit_process(process, exit_status); - } - } - - apr_pool_clear(plog); - - if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) { - ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, - 0, NULL, "Unable to open logs"); - destroy_and_exit_process(process, 1); - } - - if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) { - ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0, - NULL, "Configuration Failed"); - destroy_and_exit_process(process, 1); - } - - apr_pool_destroy(ptemp); - - for (;;) { - apr_hook_deregister_all(); - apr_pool_clear(pconf); - - for (mod = ap_prelinked_modules; *mod != NULL; mod++) { - ap_register_hooks(*mod, pconf); - } - - /* This is a hack until we finish the code so that it only reads - * the config file once and just operates on the tree already in - * memory. rbb - */ - ap_conftree = NULL; - apr_pool_create(&ptemp, pconf); - apr_pool_tag(ptemp, "ptemp"); - ap_server_root = def_server_root; - server_conf = ap_read_config(process, ptemp, confname, &ap_conftree); - if (ap_run_pre_config(pconf, plog, ptemp) != OK) { - ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, - 0, NULL, "Pre-configuration failed"); - destroy_and_exit_process(process, 1); - } - - ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp); - ap_fixup_virtual_hosts(pconf, server_conf); - ap_fini_vhost_config(pconf, server_conf); - apr_hook_sort_all(); - apr_pool_clear(plog); - if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) { - ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, - 0, NULL, "Unable to open logs"); - destroy_and_exit_process(process, 1); - } - - if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) { - ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, - 0, NULL, "Configuration Failed"); - destroy_and_exit_process(process, 1); - } - - apr_pool_destroy(ptemp); - apr_pool_lock(pconf, 1); - - ap_run_optional_fn_retrieve(); - - if (ap_mpm_run(pconf, plog, server_conf)) - break; - - apr_pool_lock(pconf, 0); - } - - apr_pool_lock(pconf, 0); - destroy_and_exit_process(process, 0); - - return 0; /* Termination 'ok' */ -} - -/* force Expat to be linked into the server executable */ -#if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP) -#include "xmlparse.h" -const XML_LChar *suck_in_expat(void); -const XML_LChar *suck_in_expat(void) -{ - return XML_ErrorString(XML_ERROR_NONE); -} -#endif /* USE_EXPAT */ - -#ifndef SHARED_CORE_BOOTSTRAP -/* - * Force apr_password_validate() into the image so that modules like - * mod_auth can use it even if they're dynamically loaded. - */ -void suck_in_apr_password_validate(void); -void suck_in_apr_password_validate(void) -{ - apr_password_validate("a", "b"); -} -#endif - -#ifdef AP_USING_AUTOCONF -/* This ugly little hack pulls any function referenced in exports.c into - * the web server. exports.c is generated during the build, and it - * has all of the APR functions specified by the apr/apr.exports and - * apr-util/aprutil.exports files. - */ -const void *suck_in_APR(void); -const void *suck_in_APR(void) -{ - extern const void *ap_ugly_hack; - - return ap_ugly_hack; -} -#endif diff --git a/rubbos/app/httpd-2.0.64/server/main.lo b/rubbos/app/httpd-2.0.64/server/main.lo deleted file mode 100644 index e79679ce..00000000 --- a/rubbos/app/httpd-2.0.64/server/main.lo +++ /dev/null @@ -1,12 +0,0 @@ -# main.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/main.o' - -# Name of the non-PIC object. -non_pic_object='main.o' - diff --git a/rubbos/app/httpd-2.0.64/server/main.o b/rubbos/app/httpd-2.0.64/server/main.o Binary files differdeleted file mode 100644 index 0602d80a..00000000 --- a/rubbos/app/httpd-2.0.64/server/main.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/.deps b/rubbos/app/httpd-2.0.64/server/mpm/.deps deleted file mode 100644 index e69de29b..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/.deps +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/MPM.NAMING b/rubbos/app/httpd-2.0.64/server/mpm/MPM.NAMING deleted file mode 100644 index 83c0694d..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/MPM.NAMING +++ /dev/null @@ -1,15 +0,0 @@ - -The following MPMs currently exist: - - prefork ....... Multi Process Model with Preforking (Apache 1.3) - perchild ...... Multi Process Model with Threading. - Constant number of processes, variable number of threads - each child process can have a different uid/gid. - mpmt_os2 ...... Multi Process Model with Threading on OS/2 - Constant number of processes, variable number of threads. - One acceptor thread per process, multiple workers threads. - winnt ......... Single Process Model with Threading on Windows NT - worker ........ Multi Process model with threads. One acceptor thread, - multiple worker threads. - netware ....... Multi-threaded MPM for Netware - beos .......... Single Process Model with Threading on BeOS diff --git a/rubbos/app/httpd-2.0.64/server/mpm/Makefile b/rubbos/app/httpd-2.0.64/server/mpm/Makefile deleted file mode 100644 index b1f2ed46..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -top_srcdir = /bottlenecks/rubbos/app/httpd-2.0.64 -top_builddir = /bottlenecks/rubbos/app/httpd-2.0.64 -srcdir = /bottlenecks/rubbos/app/httpd-2.0.64/server/mpm -builddir = /bottlenecks/rubbos/app/httpd-2.0.64/server/mpm -VPATH = /bottlenecks/rubbos/app/httpd-2.0.64/server/mpm - -SUBDIRS = $(MPM_SUBDIR_NAME) - -include $(top_builddir)/build/rules.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/Makefile.in deleted file mode 100644 index 2decbde6..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/Makefile.in +++ /dev/null @@ -1,4 +0,0 @@ - -SUBDIRS = $(MPM_SUBDIR_NAME) - -include $(top_builddir)/build/rules.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/beos/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/beos/Makefile.in deleted file mode 100644 index 3f88b041..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/beos/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libbeos.la -LTLIBRARY_SOURCES = beos.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/beos/beos.c b/rubbos/app/httpd-2.0.64/server/mpm/beos/beos.c deleted file mode 100644 index 51a17c3e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/beos/beos.c +++ /dev/null @@ -1,1159 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The new BeOS MPM! - * - * This one basically is a single process multi threaded model, but - * I couldn't be bothered adding the spmt_ to the front of the name! - * Anyway, this is still under development so it isn't yet the default - * choice. - */ - -#define CORE_PRIVATE - -#include <kernel/OS.h> -#include <unistd.h> -#include <sys/socket.h> -#include <signal.h> - -#include "apr_strings.h" -#include "apr_portable.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "ap_mpm.h" -#include "beosd.h" -#include "ap_listen.h" -#include "scoreboard.h" -#include "mpm_common.h" -#include "mpm.h" -#include "mpm_default.h" -#include "apr_thread_mutex.h" -#include "apr_poll.h" - -extern int _kset_fd_limit_(int num); - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons: - * 1) in case something goes seriously wrong, we want to stop the server starting - * threads ad infinitum and crashing the server (remember that BeOS has a 192 - * thread per team limit). - * 2) it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ - -/* we only ever have 1 main process running... */ -#define HARD_SERVER_LIMIT 1 - -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifdef NO_THREADS -#define HARD_THREAD_LIMIT 1 -#endif -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 50 -#endif - -/* - * Actual definitions of config globals - */ - -static int ap_threads_to_start=0; -static int ap_max_requests_per_thread = 0; -static int min_spare_threads=0; -static int max_spare_threads=0; -static int ap_thread_limit=0; -static int num_listening_sockets = 0; -static apr_socket_t ** listening_sockets; -apr_thread_mutex_t *accept_mutex = NULL; - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pchild; /* Pool for httpd child stuff */ - -static int server_pid; -static int mpm_state = AP_MPMQ_STARTING; - -/* Keep track of the number of worker threads currently active */ -static int worker_thread_count; -apr_thread_mutex_t *worker_thread_count_mutex; - -/* The structure used to pass unique initialization info to each thread */ -typedef struct { - int slot; - apr_pool_t *tpool; -} proc_info; - -static void check_restart(void *data); - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We use - * this value to optimize routines that have to scan the entire scoreboard. - */ -int ap_max_child_assigned = -1; -int ap_max_threads_limit = -1; - -static apr_socket_t *udp_sock; -static apr_sockaddr_t *udp_sa; - -/* shared http_main globals... */ - -server_rec *ap_server_conf; - -/* one_process */ -static int one_process = 0; - -#ifdef DEBUG_SIGSTOP -int raise_sigstop_flags; -#endif - -/* a clean exit from a child with proper cleanup - static void clean_child_exit(int code) __attribute__ ((noreturn)); */ -static void clean_child_exit(int code) -{ - if (pchild) - apr_pool_destroy(pchild); - exit(code); -} - -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - chdir(ap_coredump_dir); - signal(sig, SIG_DFL); - kill(server_pid, sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - -/***************************************************************** - * Connection structures and accounting... - */ - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; -static int volatile child_fatal; -ap_generation_t volatile ap_my_generation = 0; - -/* - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at - * functions to initiate shutdown or restart without relying on signals. - * Previously this was initiated in sig_term() and restart() signal handlers, - * but we want to be able to start a shutdown/restart from other sources -- - * e.g. on Win32, from the service manager. Now the service manager can - * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that - * these functions can also be called by the child processes, since global - * variables are no longer used to pass on the required action to the parent. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. - */ - -static void ap_start_shutdown(void) -{ - mpm_state = AP_MPMQ_STOPPING; - - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; -} - -/* do a graceful restart if graceful == 1 */ -static void ap_start_restart(int graceful) -{ - mpm_state = AP_MPMQ_STOPPING; - - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = graceful; -} - -static void sig_term(int sig) -{ - ap_start_shutdown(); -} - -static void restart(int sig) -{ - ap_start_restart(sig == AP_SIG_GRACEFUL); -} - -static void tell_workers_to_exit(void) -{ - apr_size_t len; - int i = 0; - - mpm_state = AP_MPMQ_STOPPING; - - for (i = 0 ; i < ap_max_child_assigned; i++){ - len = 4; - if (apr_sendto(udp_sock, udp_sa, 0, "die!", &len) != APR_SUCCESS) - break; - } -} - -static void set_signals(void) -{ - struct sigaction sa; - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - if (!one_process) { - sa.sa_handler = sig_coredump; - - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)"); - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)"); - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)"); - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)"); - sa.sa_flags = 0; - } - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); - - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)"); - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -} - -/***************************************************************** - * Here follows a long bunch of generic server bookkeeping stuff... - */ - -int ap_graceful_stop_signalled(void) -{ - /* XXX - Does this really work? - Manoj */ - return is_graceful; -} - -/***************************************************************** - * Child process main loop. - */ - -static void process_socket(apr_pool_t *p, apr_socket_t *sock, - int my_child_num, apr_bucket_alloc_t *bucket_alloc) -{ - conn_rec *current_conn; - long conn_id = my_child_num; - int csd; - ap_sb_handle_t *sbh; - - (void)apr_os_sock_get(&csd, sock); - - if (csd >= FD_SETSIZE) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, - "filedescriptor (%u) larger than FD_SETSIZE (%u) " - "found, you probably need to rebuild Apache with a " - "larger FD_SETSIZE", csd, FD_SETSIZE); - apr_socket_close(sock); - return; - } - - ap_create_sb_handle(&sbh, p, 0, my_child_num); - current_conn = ap_run_create_connection(p, ap_server_conf, - sock, conn_id, sbh, - bucket_alloc); - - if (current_conn) { - ap_process_connection(current_conn, sock); - ap_lingering_close(current_conn); - } -} - -static int32 worker_thread(void * dummy) -{ - proc_info * ti = dummy; - int child_slot = ti->slot; - apr_pool_t *tpool = ti->tpool; - apr_allocator_t *allocator; - apr_socket_t *csd = NULL; - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - apr_bucket_alloc_t *bucket_alloc; - apr_socket_t *sd = NULL; - apr_status_t rv = APR_EINIT; - int srv , n; - int curr_pollfd = 0, last_pollfd = 0; - sigset_t sig_mask; - int requests_this_child = ap_max_requests_per_thread; - apr_pollfd_t *pollset; - /* each worker thread is in control of its own destiny...*/ - int this_worker_should_exit = 0; - free(ti); - - mpm_state = AP_MPMQ_STARTING; - - on_exit_thread(check_restart, (void*)child_slot); - - /* block the signals for this thread */ - sigfillset(&sig_mask); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); - - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - apr_pool_create_ex(&ptrans, tpool, NULL, allocator); - apr_allocator_owner_set(allocator, ptrans); - - apr_pool_tag(ptrans, "transaction"); - - bucket_alloc = apr_bucket_alloc_create_ex(allocator); - - apr_thread_mutex_lock(worker_thread_count_mutex); - worker_thread_count++; - apr_thread_mutex_unlock(worker_thread_count_mutex); - - (void) ap_update_child_status_from_indexes(0, child_slot, SERVER_STARTING, - (request_rec*)NULL); - - apr_poll_setup(&pollset, num_listening_sockets + 1, tpool); - for(n=0 ; n <= num_listening_sockets ; n++) - apr_poll_socket_add(pollset, listening_sockets[n], APR_POLLIN); - - mpm_state = AP_MPMQ_RUNNING; - - while (1) { - /* If we're here, then chances are (unless we're the first thread created) - * we're going to be held up in the accept mutex, so doing this here - * shouldn't hurt performance. - */ - - this_worker_should_exit |= (ap_max_requests_per_thread != 0) && (requests_this_child <= 0); - - if (this_worker_should_exit) break; - - (void) ap_update_child_status_from_indexes(0, child_slot, SERVER_READY, - (request_rec*)NULL); - - apr_thread_mutex_lock(accept_mutex); - - while (!this_worker_should_exit) { - apr_int16_t event; - apr_status_t ret; - - ret = apr_poll(pollset, num_listening_sockets + 1, &srv, -1); - - if (ret != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(ret)) { - continue; - } - /* poll() will only return errors in catastrophic - * circumstances. Let's try exiting gracefully, for now. */ - ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) - ap_server_conf, "apr_poll: (listen)"); - this_worker_should_exit = 1; - } else { - /* if we've bailed in apr_poll what's the point of trying to use the data? */ - apr_poll_revents_get(&event, listening_sockets[0], pollset); - - if (event & APR_POLLIN){ - apr_sockaddr_t *rec_sa; - apr_size_t len = 5; - char *tmpbuf = apr_palloc(ptrans, sizeof(char) * 5); - apr_sockaddr_info_get(&rec_sa, "127.0.0.1", APR_UNSPEC, 7772, 0, ptrans); - - if ((ret = apr_recvfrom(rec_sa, listening_sockets[0], 0, tmpbuf, &len)) - != APR_SUCCESS){ - ap_log_error(APLOG_MARK, APLOG_ERR, ret, NULL, - "error getting data from UDP!!"); - }else { - /* add checking??? */ - } - this_worker_should_exit = 1; - } - } - - if (this_worker_should_exit) break; - - if (num_listening_sockets == 1) { - sd = ap_listeners->sd; - goto got_fd; - } - else { - /* find a listener */ - curr_pollfd = last_pollfd; - do { - curr_pollfd++; - - if (curr_pollfd > num_listening_sockets) - curr_pollfd = 1; - - /* Get the revent... */ - apr_poll_revents_get(&event, listening_sockets[curr_pollfd], pollset); - - if (event & APR_POLLIN) { - last_pollfd = curr_pollfd; - sd = listening_sockets[curr_pollfd]; - goto got_fd; - } - } while (curr_pollfd != last_pollfd); - } - } - got_fd: - - if (!this_worker_should_exit) { - rv = apr_accept(&csd, sd, ptrans); - - apr_thread_mutex_unlock(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, - "apr_accept"); - } else { - process_socket(ptrans, csd, child_slot, bucket_alloc); - requests_this_child--; - } - } - else { - apr_thread_mutex_unlock(accept_mutex); - break; - } - apr_pool_clear(ptrans); - } - - ap_update_child_status_from_indexes(0, child_slot, SERVER_DEAD, (request_rec*)NULL); - - apr_bucket_alloc_destroy(bucket_alloc); - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, - "worker_thread %ld exiting", find_thread(NULL)); - - apr_thread_mutex_lock(worker_thread_count_mutex); - worker_thread_count--; - apr_thread_mutex_unlock(worker_thread_count_mutex); - - return (0); -} - -static int make_worker(int slot) -{ - thread_id tid; - proc_info *my_info = (proc_info *)malloc(sizeof(proc_info)); /* freed by thread... */ - - if (my_info == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - my_info->slot = slot; - apr_pool_create(&my_info->tpool, pchild); - - if (slot + 1 > ap_max_child_assigned) - ap_max_child_assigned = slot + 1; - - if (one_process) { - set_signals(); - ap_scoreboard_image->parent[0].pid = getpid(); - return 0; - } - - (void) ap_update_child_status_from_indexes(0, slot, SERVER_STARTING, (request_rec*)NULL); - tid = spawn_thread(worker_thread, "apache_worker", B_NORMAL_PRIORITY, - my_info); - if (tid < B_NO_ERROR) { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, - "spawn_thread: Unable to start a new thread"); - /* In case system resources are maxxed out, we don't want - * Apache running away with the CPU trying to fork over and - * over and over again. - */ - (void) ap_update_child_status_from_indexes(0, slot, SERVER_DEAD, - (request_rec*)NULL); - - sleep(10); - free(my_info); - - return -1; - } - resume_thread(tid); - - ap_scoreboard_image->servers[0][slot].tid = tid; - return 0; -} - -static void check_restart(void *data) -{ - if (!restart_pending && !shutdown_pending) { - int slot = (int)data; - make_worker(slot); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, - "spawning a new worker thread in slot %d", slot); - } -} - -/* start up a bunch of children */ -static void startup_threads(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < ap_thread_limit; ++i) { - if (ap_scoreboard_image->servers[0][i].tid) { - continue; - } - if (make_worker(i) < 0) { - break; - } - --number_to_start; - } -} - - -/* - * spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough idle servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (32) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_idle_server_maintenance(void) -{ - int i; - int free_length; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead = -1; - - /* initialize the free_list */ - free_length = 0; - - for (i = 0; i < ap_thread_limit; ++i) { - if (ap_scoreboard_image->servers[0][i].tid == 0) { - if (free_length < spawn_rate) { - free_slots[free_length] = i; - ++free_length; - } - } - else { - last_non_dead = i; - } - - if (i >= ap_max_child_assigned && free_length >= spawn_rate) { - break; - } - } - ap_max_child_assigned = last_non_dead + 1; - - if (free_length > 0) { - for (i = 0; i < free_length; ++i) { - make_worker(free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } else if (spawn_rate < MAX_SPAWN_RATE) { - spawn_rate *= 2; - } - } else { - spawn_rate = 1; - } -} - -static void server_main_loop(int remaining_threads_to_start) -{ - int child_slot; - apr_exit_why_e exitwhy; - int status; - apr_proc_t pid; - int i; - - while (!restart_pending && !shutdown_pending) { - - ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); - - if (pid.pid >= 0) { - if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) { - shutdown_pending = 1; - child_fatal = 1; - return; - } - /* non-fatal death... note that it's gone in the scoreboard. */ - child_slot = -1; - for (i = 0; i < ap_max_child_assigned; ++i) { - if (ap_scoreboard_image->servers[0][i].tid == pid.pid) { - child_slot = i; - break; - } - } - if (child_slot >= 0) { - ap_scoreboard_image->servers[0][child_slot].tid = 0; - (void) ap_update_child_status_from_indexes(0, child_slot, - SERVER_DEAD, - (request_rec*)NULL); - - if (remaining_threads_to_start - && child_slot < ap_thread_limit) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - make_worker(child_slot); - --remaining_threads_to_start; - } -#if APR_HAS_OTHER_CHILD - } - else if (apr_proc_other_child_read(&pid, status) == 0) { - /* handled */ -#endif - } - else if (is_graceful) { - /* Great, we've probably just lost a slot in the - * scoreboard. Somehow we don't know about this - * child. - */ - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, - "long lost child came home! (pid %ld)", pid.pid); - } - - /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ - continue; - } - else if (remaining_threads_to_start) { - /* we hit a 1 second timeout in which none of the previous - * generation of children needed to be reaped... so assume - * they're all done, and pick up the slack if any is left. - */ - startup_threads(remaining_threads_to_start); - remaining_threads_to_start = 0; - /* In any event we really shouldn't do the code below because - * few of the servers we just started are in the IDLE state - * yet, so we'd mistakenly create an extra server. - */ - continue; - } - perform_idle_server_maintenance(); - } -} - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_max_child_assigned; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = HARD_SERVER_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = HARD_THREAD_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = HARD_THREAD_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = max_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = min_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_thread; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = HARD_SERVER_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - int remaining_threads_to_start, i,j; - apr_status_t rv; - ap_listen_rec *lr; - pconf = _pconf; - ap_server_conf = s; - - /* Increase the available pool of fd's. This code from - * Joe Kloss <joek@be.com> - */ - if( FD_SETSIZE > 128 && (i = _kset_fd_limit_( 128 )) < 0 ){ - ap_log_error(APLOG_MARK, APLOG_ERR, i, s, - "could not set FD_SETSIZE (_kset_fd_limit_ failed)"); - } - - /* BeOS R5 doesn't support pipes on select() calls, so we use a - UDP socket as these are supported in both R5 and BONE. If we only cared - about BONE we'd use a pipe, but there it is. - As we have UDP support in APR, now use the APR functions and check all the - return values... - */ - if (apr_sockaddr_info_get(&udp_sa, "127.0.0.1", APR_UNSPEC, 7772, 0, _pconf) - != APR_SUCCESS){ - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s, - "couldn't create control socket information, shutting down"); - return 1; - } - if (apr_socket_create(&udp_sock, udp_sa->family, SOCK_DGRAM, - _pconf) != APR_SUCCESS){ - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s, - "couldn't create control socket, shutting down"); - return 1; - } - if (apr_bind(udp_sock, udp_sa) != APR_SUCCESS){ - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s, - "couldn't bind UDP socket!"); - return 1; - } - - if ((num_listening_sockets = ap_setup_listeners(ap_server_conf)) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, - "no listening sockets available, shutting down"); - return 1; - } - - ap_log_pid(pconf, ap_pid_fname); - - /* - * Create our locks... - */ - - /* accept_mutex - * used to lock around select so we only have one thread - * in select at a time - */ - rv = apr_thread_mutex_create(&accept_mutex, 0, pconf); - if (rv != APR_SUCCESS) { - /* tsch tsch, can't have more than one thread in the accept loop - at a time so we need to fall on our sword... */ - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock"); - return 1; - } - - /* worker_thread_count_mutex - * locks the worker_thread_count so we have ana ccurate count... - */ - rv = apr_thread_mutex_create(&worker_thread_count_mutex, 0, pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create worker thread count lock"); - return 1; - } - - /* - * Startup/shutdown... - */ - - if (!is_graceful) { - /* setup the scoreboard shared memory */ - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - return 1; - } - - for (i = 0; i < HARD_SERVER_LIMIT; i++) { - ap_scoreboard_image->parent[i].pid = 0; - for (j = 0;j < HARD_THREAD_LIMIT; j++) - ap_scoreboard_image->servers[i][j].tid = 0; - } - } - - if (HARD_SERVER_LIMIT == 1) - ap_scoreboard_image->parent[0].pid = getpid(); - - set_signals(); - - /* Sanity checks to avoid thrashing... */ - if (max_spare_threads < min_spare_threads ) - max_spare_threads = min_spare_threads; - - /* If we're doing a graceful_restart then we're going to see a lot - * of threads exiting immediately when we get into the main loop - * below (because we just sent them AP_SIG_GRACEFUL). This happens - * pretty rapidly... and for each one that exits we'll start a new one - * until we reach at least threads_min_free. But we may be permitted to - * start more than that, so we'll just keep track of how many we're - * supposed to start up without the 1 second penalty between each fork. - */ - remaining_threads_to_start = ap_threads_to_start; - /* sanity check on the number to start... */ - if (remaining_threads_to_start > ap_thread_limit) { - remaining_threads_to_start = ap_thread_limit; - } - - /* setup the child pool to use for the workers. Each worker creates - * a seperate pool of its own to use. - */ - apr_pool_create(&pchild, pconf); - - /* Now that we have the child pool (pchild) we can allocate - * the listenfds and creat the pollset... - */ - listening_sockets = apr_palloc(pchild, - sizeof(*listening_sockets) * (num_listening_sockets + 1)); - - listening_sockets[0] = udp_sock; - for (lr = ap_listeners, i = 1; i <= num_listening_sockets; lr = lr->next, ++i) - listening_sockets[i]=lr->sd; - - /* we assume all goes OK...hmm might want to check that! */ - /* if we're in one_process mode we don't want to start threads - * do we?? - */ - if (!is_graceful && !one_process) { - startup_threads(remaining_threads_to_start); - remaining_threads_to_start = 0; - } - else { - /* give the system some time to recover before kicking into - * exponential mode */ - hold_off_on_exponential_spawning = 10; - } - - /* - * record that we've entered the world ! - */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); - - restart_pending = shutdown_pending = 0; - - /* - * main_loop until it's all over - */ - if (!one_process) { - server_main_loop(remaining_threads_to_start); - - tell_workers_to_exit(); /* if we get here we're exiting... */ - sleep(1); /* give them a brief chance to exit */ - } else { - proc_info *my_info = (proc_info *)malloc(sizeof(proc_info)); - my_info->slot = 0; - apr_pool_create(&my_info->tpool, pchild); - worker_thread(my_info); - } - - /* close the UDP socket we've been using... */ - apr_socket_close(listening_sockets[0]); - - if ((one_process || shutdown_pending) && !child_fatal) { - const char *pidfile = NULL; - pidfile = ap_server_root_relative (pconf, ap_pid_fname); - if ( pidfile != NULL && unlink(pidfile) == 0) - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "removed PID file %s (pid=%ld)", pidfile, - (long)getpid()); - } - - if (one_process) { - return 1; - } - - /* - * If we get here we're shutting down... - */ - if (shutdown_pending) { - /* Time to gracefully shut down: - * Kill child processes, tell them to call child_exit, etc... - */ - if (beosd_killpg(getpgrp(), SIGTERM) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "killpg SIGTERM"); - - /* use ap_reclaim_child_processes starting with SIGTERM */ - ap_reclaim_child_processes(1); - - if (!child_fatal) { /* already recorded */ - /* record the shutdown in the log */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "caught SIGTERM, shutting down"); - } - - return 1; - } - - /* we've been told to restart */ - signal(SIGHUP, SIG_IGN); - - if (is_graceful) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); - } - else { - /* Kill 'em all. Since the child acts the same on the parents SIGTERM - * and a SIGHUP, we may as well use the same signal, because some user - * pthreads are stealing signals from us left and right. - */ - - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "SIGHUP received. Attempting to restart"); - } - - /* just before we go, tidy up the locks we've created to prevent a - * potential leak of semaphores... */ - apr_thread_mutex_destroy(worker_thread_count_mutex); - apr_thread_mutex_destroy(accept_mutex); - - return 0; -} - -static int beos_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) -{ - static int restart_num = 0; - int no_detach, debug, foreground; - apr_status_t rv; - - mpm_state = AP_MPMQ_STARTING; - - debug = ap_exists_config_define("DEBUG"); - - if (debug) { - foreground = one_process = 1; - no_detach = 0; - } - else - { - one_process = ap_exists_config_define("ONE_PROCESS"); - no_detach = ap_exists_config_define("NO_DETACH"); - foreground = ap_exists_config_define("FOREGROUND"); - } - - /* sigh, want this only the second time around */ - if (restart_num++ == 1) { - is_graceful = 0; - - if (!one_process && !foreground) { - rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND - : APR_PROC_DETACH_DAEMONIZE); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "apr_proc_detach failed"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - - server_pid = getpid(); - } - - beosd_pre_config(); - ap_listen_pre_config(); - ap_threads_to_start = DEFAULT_START_THREADS; - min_spare_threads = DEFAULT_MIN_FREE_THREADS; - max_spare_threads = DEFAULT_MAX_FREE_THREADS; - ap_thread_limit = HARD_THREAD_LIMIT; - ap_pid_fname = DEFAULT_PIDLOG; - ap_max_requests_per_thread = DEFAULT_MAX_REQUESTS_PER_THREAD; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - return OK; -} - -static void beos_hooks(apr_pool_t *p) -{ - one_process = 0; - - ap_hook_pre_config(beos_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); -} - -static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_to_start = atoi(arg); - if (ap_threads_to_start < 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "StartThreads set to a value less than 0, reset to 1"); - ap_threads_to_start = 1; - } - return NULL; -} - -static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - min_spare_threads = atoi(arg); - if (min_spare_threads <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - min_spare_threads = 1; - } - - return NULL; -} - -static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - max_spare_threads = atoi(arg); - return NULL; -} - -static const char *set_threads_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_thread_limit = atoi(arg); - if (ap_thread_limit > HARD_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients of %d exceeds compile time limit " - "of %d servers,", ap_thread_limit, HARD_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering MaxClients to %d. To increase, please " - "see the", HARD_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " HARD_THREAD_LIMIT define in server/mpm/beos/mpm_default.h."); - ap_thread_limit = HARD_THREAD_LIMIT; - } - else if (ap_thread_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require MaxClients > 0, setting to %d", HARD_THREAD_LIMIT); - ap_thread_limit = HARD_THREAD_LIMIT; - } - return NULL; -} - -static const char *set_max_requests_per_thread (cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_max_requests_per_thread = atoi(arg); - if (ap_max_requests_per_thread < 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxRequestsPerThread was set below 0" - "reset to 0, but this may not be what you want."); - ap_max_requests_per_thread = 0; - } - - return NULL; -} - -static const command_rec beos_cmds[] = { -BEOS_DAEMON_COMMANDS, -LISTEN_COMMANDS, -AP_INIT_TAKE1( "StartThreads", set_threads_to_start, NULL, RSRC_CONF, - "Number of threads to launch at server startup"), -AP_INIT_TAKE1( "MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, - "Minimum number of idle children, to handle request spikes"), -AP_INIT_TAKE1( "MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, - "Maximum number of idle children" ), -AP_INIT_TAKE1( "MaxClients", set_threads_limit, NULL, RSRC_CONF, - "Maximum number of children alive at the same time (max threads)" ), -AP_INIT_TAKE1( "MaxRequestsPerThread", set_max_requests_per_thread, NULL, RSRC_CONF, - "Maximum number of requests served by a thread" ), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_beos_module = { - MPM20_MODULE_STUFF, - NULL, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - beos_cmds, /* command apr_table_t */ - beos_hooks /* register_hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/beos/beos.h b/rubbos/app/httpd-2.0.64/server/mpm/beos/beos.h deleted file mode 100644 index eb8a5509..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/beos/beos.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_BEOS_H -#define APACHE_MPM_BEOS_H - -extern int ap_threads_per_child; -extern int ap_pipe_of_death[2]; -extern int ap_extended_status; -extern void clean_child_exit(int); -extern int max_daemons_limit; - -#endif /* APACHE_MPM_BEOS_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/beos/config5.m4 b/rubbos/app/httpd-2.0.64/server/mpm/beos/config5.m4 deleted file mode 100644 index 4f201408..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/beos/config5.m4 +++ /dev/null @@ -1,7 +0,0 @@ -dnl ## XXX - Need a more thorough check of the proper flags to use - -if test "$MPM_NAME" = "beos" ; then - apache_apr_flags="--enable-threads" - - APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/beos/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/beos/mpm.h deleted file mode 100644 index 57221b1c..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/beos/mpm.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_BEOS_H -#define APACHE_MPM_BEOS_H - -#define BEOS_MPM -#include "scoreboard.h" - -#define MPM_NAME "Beos" -#define MPM_CHILD_PID(i) (ap_scoreboard_image->servers[0][i].tid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) - -#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -#define AP_MPM_WANT_WAIT_OR_TIMEOUT -#define AP_MPM_WANT_PROCESS_CHILD_STATUS -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_MAX_MEM_FREE - -extern int ap_max_child_assigned; -extern server_rec *ap_server_conf; -extern int ap_threads_per_child; - -#endif /* APACHE_MPM_BEOS_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/beos/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/beos/mpm_default.h deleted file mode 100644 index 7bd0ce48..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/beos/mpm_default.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* we use the child (c) as zero in our code... */ -#define AP_ID_FROM_CHILD_THREAD(c, t) t -/* as the child is always zero, just return the id... */ -#define AP_CHILD_THREAD_FROM_ID(i) 0 , i - -/* Number of threads to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_THREADS -#define DEFAULT_START_THREADS 10 -#endif - -#ifdef NO_THREADS -#define DEFAULT_THREADS 1 -#endif -#ifndef DEFAULT_THREADS -#define DEFAULT_THREADS 10 -#endif - -/* The following 2 settings are used to control the number of threads - * we have available. Normally the DEFAULT_MAX_FREE_THREADS is set - * to the same as the HARD_THREAD_LIMIT to avoid churning of starting - * new threads to replace threads killed off... - */ - -/* Maximum number of *free* threads --- more than this, and - * they will die off. - */ -#ifndef DEFAULT_MAX_FREE_THREADS -#define DEFAULT_MAX_FREE_THREADS HARD_THREAD_LIMIT -#endif - -/* Minimum --- fewer than this, and more will be created */ -#ifndef DEFAULT_MIN_FREE_THREADS -#define DEFAULT_MIN_FREE_THREADS 1 -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If == 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_THREAD -#define DEFAULT_MAX_REQUESTS_PER_THREAD 0 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/config.m4 b/rubbos/app/httpd-2.0.64/server/mpm/config.m4 deleted file mode 100644 index c86a624e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/config.m4 +++ /dev/null @@ -1,45 +0,0 @@ -AC_MSG_CHECKING(which MPM to use) -AC_ARG_WITH(mpm, -APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use. - MPM={beos|worker|prefork|mpmt_os2|perchild|leader|threadpool}),[ - APACHE_MPM=$withval -],[ - if test "x$APACHE_MPM" = "x"; then - APACHE_MPM=prefork - fi -]) -AC_MSG_RESULT($APACHE_MPM) - -apache_cv_mpm=$APACHE_MPM - -if test "$apache_cv_mpm" = "worker" -o "$apache_cv_mpm" = "perchild" -o "$apache_cv_mpm" = "leader" -o "$apache_cv_mpm" = "threadpool" ; then - APR_CHECK_APR_DEFINE(APR_HAS_THREADS) - - if test "x$ac_cv_define_APR_HAS_THREADS" = "xno"; then - AC_MSG_RESULT(The currently selected MPM requires threads which your system seems to lack) - AC_MSG_CHECKING(checking for replacement) - AC_MSG_RESULT(prefork selected) - apache_cv_mpm=prefork - fi -fi - -APACHE_FAST_OUTPUT(server/mpm/Makefile) - -MPM_NAME=$apache_cv_mpm -if test "$MPM_NAME" = "leader" -o "$MPM_NAME" = "threadpool" -o "$MPM_NAME" = "perchild"; then - AC_MSG_WARN(You have selected an EXPERIMENTAL MPM. Be warned!) - MPM_SUBDIR_NAME=experimental/$MPM_NAME -else - MPM_SUBDIR_NAME=$MPM_NAME -fi -MPM_DIR=server/mpm/$MPM_SUBDIR_NAME -MPM_LIB=$MPM_DIR/lib${MPM_NAME}.la - -if test ! -f "$abs_srcdir/$MPM_DIR/mpm.h"; then - AC_MSG_ERROR(the selected mpm -- $apache_cv_mpm -- is not supported) -fi - -APACHE_SUBST(MPM_NAME) -APACHE_SUBST(MPM_SUBDIR_NAME) -MODLIST="$MODLIST mpm_${MPM_NAME}" - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/Makefile.in deleted file mode 100644 index 03f1765e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libleader.la -LTLIBRARY_SOURCES = leader.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/README b/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/README deleted file mode 100644 index 1981a5be..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/README +++ /dev/null @@ -1,15 +0,0 @@ -Leader MPM: -This is an experimental variant of the standard worker MPM. -It uses a Leader/Followers design pattern to coordinate work among threads: -http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf - -To use the leader MPM, add "--with-mpm=leader" to the configure -script's arguments when building the httpd. - -This MPM depends on APR's atomic compare-and-swap operations for -thread synchronization. If you are compiling for an x86 target -and you don't need to support 386s, or you're compiling for a -SPARC and you don't need to run on pre-UltraSPARC chips, add -"--enable-nonportable-atomics=yes" to the configure script's -arguments. This will cause APR to implement atomic operations -using efficient opcodes not available in older CPUs. diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/config5.m4 b/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/config5.m4 deleted file mode 100644 index 9a915abf..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/config5.m4 +++ /dev/null @@ -1,6 +0,0 @@ -dnl ## XXX - Need a more thorough check of the proper flags to use - -if test "$MPM_NAME" = "leader" ; then - AC_CHECK_FUNCS(pthread_kill) - APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/leader.c b/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/leader.c deleted file mode 100644 index 322c2286..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/leader.c +++ /dev/null @@ -1,1976 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_portable.h" -#include "apr_strings.h" -#include "apr_file_io.h" -#include "apr_thread_proc.h" -#include "apr_signal.h" -#include "apr_thread_cond.h" -#include "apr_thread_mutex.h" -#include "apr_proc_mutex.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#if APR_HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif -#ifdef HAVE_SYS_PROCESSOR_H -#include <sys/processor.h> /* for bindprocessor() */ -#endif - -#if !APR_HAS_THREADS -#error The Leader/Follower MPM requires APR threads, but they are unavailable. -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "ap_mpm.h" -#include "mpm_common.h" -#include "ap_listen.h" -#include "scoreboard.h" -#include "mpm_default.h" -#include "apr_poll.h" - -#include <signal.h> -#include <limits.h> /* for INT_MAX */ - -#include "apr_atomic.h" - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_SERVER_LIMIT -#define DEFAULT_SERVER_LIMIT 16 -#endif - -/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_SERVER_LIMIT -#define MAX_SERVER_LIMIT 20000 -#endif - -/* Limit on the threads per process. Clients will be locked out if more than - * this * server_limit are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_THREAD_LIMIT -#define DEFAULT_THREAD_LIMIT 64 -#endif - -/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_THREAD_LIMIT -#define MAX_THREAD_LIMIT 20000 -#endif - -/* - * Actual definitions of config globals - */ - -int ap_threads_per_child = 0; /* Worker threads per child */ -static int ap_daemons_to_start = 0; -static int min_spare_threads = 0; -static int max_spare_threads = 0; -static int ap_daemons_limit = 0; -static int server_limit = DEFAULT_SERVER_LIMIT; -static int first_server_limit; -static int thread_limit = DEFAULT_THREAD_LIMIT; -static int first_thread_limit; -static int changed_limit_at_restart; -static int dying = 0; -static int workers_may_exit = 0; -static int start_thread_may_exit = 0; -static int requests_this_child; -static int num_listensocks = 0; -static int resource_shortage = 0; -static int mpm_state = AP_MPMQ_STARTING; - -typedef struct worker_wakeup_info worker_wakeup_info; - -/* The structure used to pass unique initialization info to each thread */ -typedef struct { - int pid; - int tid; - int sd; -} proc_info; - - -/* Structure used to pass information to the thread responsible for - * creating the rest of the threads. - */ -typedef struct { - apr_thread_t **threads; - int child_num_arg; - apr_threadattr_t *threadattr; -} thread_starter; - -#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We - * use this value to optimize routines that have to scan the entire - * scoreboard. - */ -int ap_max_daemons_limit = -1; - -static ap_pod_t *pod; - -/* *Non*-shared http_main globals... */ - -server_rec *ap_server_conf; - -/* This MPM respects a couple of runtime flags that can aid in debugging. - * Setting the -DNO_DETACH flag will prevent the root process from - * detaching from its controlling terminal. Additionally, setting - * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the - * child_main loop running in the process which originally started up. - * This gives you a pretty nice debugging environment. (You'll get a SIGHUP - * early in standalone_main; just continue through. This is the server - * trying to kill off any child processes which it might have lying - * around --- Apache doesn't keep track of their pids, it just sends - * SIGHUP to the process group, ignoring it in the root process. - * Continue through and you'll be fine.). - */ - -static int one_process = 0; - -#ifdef DEBUG_SIGSTOP -int raise_sigstop_flags; -#endif - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pchild; /* Pool for httpd child stuff */ - -static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main - thread. Use this instead */ -static pid_t parent_pid; - -/* Locks for accept serialization */ -static apr_proc_mutex_t *accept_mutex; - -#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT -#define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS) -#else -#define SAFE_ACCEPT(stmt) (stmt) -#endif - - -/* Structure used to wake up an idle worker thread - */ -struct worker_wakeup_info { - apr_uint32_t next; /* index into worker_wakeups array, - * used to build a linked list - */ - apr_thread_cond_t *cond; - apr_thread_mutex_t *mutex; -}; - -static worker_wakeup_info *worker_wakeup_create(apr_pool_t *pool) -{ - apr_status_t rv; - worker_wakeup_info *wakeup; - - wakeup = (worker_wakeup_info *)apr_palloc(pool, sizeof(*wakeup)); - if ((rv = apr_thread_cond_create(&wakeup->cond, pool)) != APR_SUCCESS) { - return NULL; - } - if ((rv = apr_thread_mutex_create(&wakeup->mutex, APR_THREAD_MUTEX_DEFAULT, - pool)) != APR_SUCCESS) { - return NULL; - } - /* The wakeup's mutex will be unlocked automatically when - * the worker blocks on the condition variable - */ - apr_thread_mutex_lock(wakeup->mutex); - return wakeup; -} - - -/* Structure used to hold a stack of idle worker threads - */ -typedef struct { - /* 'state' consists of several fields concatenated into a - * single 32-bit int for use with the apr_atomic_cas() API: - * state & STACK_FIRST is the thread ID of the first thread - * in a linked list of idle threads - * state & STACK_TERMINATED indicates whether the proc is shutting down - * state & STACK_NO_LISTENER indicates whether the process has - * no current listener thread - */ - apr_uint32_t state; -} worker_stack; - -#define STACK_FIRST 0xffff -#define STACK_LIST_END 0xffff -#define STACK_TERMINATED 0x10000 -#define STACK_NO_LISTENER 0x20000 - -static worker_wakeup_info **worker_wakeups = NULL; - -static worker_stack* worker_stack_create(apr_pool_t *pool, apr_size_t max) -{ - worker_stack *stack = (worker_stack *)apr_palloc(pool, sizeof(*stack)); - stack->state = STACK_NO_LISTENER | STACK_LIST_END; - return stack; -} - -static apr_status_t worker_stack_wait(worker_stack *stack, - apr_uint32_t worker_id) -{ - worker_wakeup_info *wakeup = worker_wakeups[worker_id]; - - while (1) { - apr_uint32_t state = stack->state; - if (state & (STACK_TERMINATED | STACK_NO_LISTENER)) { - if (state & STACK_TERMINATED) { - return APR_EINVAL; - } - if (apr_atomic_cas(&(stack->state), STACK_LIST_END, state) != - state) { - continue; - } - else { - return APR_SUCCESS; - } - } - wakeup->next = state; - if (apr_atomic_cas(&(stack->state), worker_id, state) != state) { - continue; - } - else { - return apr_thread_cond_wait(wakeup->cond, wakeup->mutex); - } - } -} - -static apr_status_t worker_stack_awaken_next(worker_stack *stack) -{ - - while (1) { - apr_uint32_t state = stack->state; - apr_uint32_t first = state & STACK_FIRST; - if (first == STACK_LIST_END) { - if (apr_atomic_cas(&(stack->state), state | STACK_NO_LISTENER, - state) != state) { - continue; - } - else { - return APR_SUCCESS; - } - } - else { - worker_wakeup_info *wakeup = worker_wakeups[first]; - if (apr_atomic_cas(&(stack->state), (state ^ first) | wakeup->next, - state) != state) { - continue; - } - else { - /* Acquire and release the idle worker's mutex to ensure - * that it's actually waiting on its condition variable - */ - apr_status_t rv; - if ((rv = apr_thread_mutex_lock(wakeup->mutex)) != - APR_SUCCESS) { - return rv; - } - if ((rv = apr_thread_mutex_unlock(wakeup->mutex)) != - APR_SUCCESS) { - return rv; - } - return apr_thread_cond_signal(wakeup->cond); - } - } - } -} - -static apr_status_t worker_stack_term(worker_stack *stack) -{ - int i; - apr_status_t rv; - - while (1) { - apr_uint32_t state = stack->state; - if (apr_atomic_cas(&(stack->state), state | STACK_TERMINATED, - state) == state) { - break; - } - } - for (i = 0; i < ap_threads_per_child; i++) { - if ((rv = worker_stack_awaken_next(stack)) != APR_SUCCESS) { - return rv; - } - } - return APR_SUCCESS; -} - -static worker_stack *idle_worker_stack; - -#define ST_INIT 0 -#define ST_GRACEFUL 1 -#define ST_UNGRACEFUL 2 - -static int terminate_mode = ST_INIT; - -static void signal_threads(int mode) -{ - if (terminate_mode == mode) { - return; - } - terminate_mode = mode; - mpm_state = AP_MPMQ_STOPPING; - workers_may_exit = 1; - - worker_stack_term(idle_worker_stack); -} - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_max_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_STATIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = server_limit; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = thread_limit; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = ap_threads_per_child; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = min_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = max_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = ap_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -/* a clean exit from a child with proper cleanup */ -static void clean_child_exit(int code) __attribute__ ((noreturn)); -static void clean_child_exit(int code) -{ - mpm_state = AP_MPMQ_STOPPING; - if (pchild) { - apr_pool_destroy(pchild); - } - ap_mpm_pod_close(pod); - exit(code); -} - -static void just_die(int sig) -{ - clean_child_exit(0); -} - -/***************************************************************** - * Connection structures and accounting... - */ - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; -static volatile int child_fatal; -ap_generation_t volatile ap_my_generation; - -/* - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at - * functions to initiate shutdown or restart without relying on signals. - * Previously this was initiated in sig_term() and restart() signal handlers, - * but we want to be able to start a shutdown/restart from other sources -- - * e.g. on Win32, from the service manager. Now the service manager can - * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that - * these functions can also be called by the child processes, since global - * variables are no longer used to pass on the required action to the parent. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. - */ - -static void ap_start_shutdown(void) -{ - mpm_state = AP_MPMQ_STOPPING; - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; -} - -/* do a graceful restart if graceful == 1 */ -static void ap_start_restart(int graceful) -{ - mpm_state = AP_MPMQ_STOPPING; - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = graceful; -} - -static void sig_term(int sig) -{ - if (ap_my_pid == parent_pid) { - ap_start_shutdown(); - } - else { - signal_threads(ST_GRACEFUL); - } -} - -static void restart(int sig) -{ - ap_start_restart(sig == AP_SIG_GRACEFUL); -} - -static void set_signals(void) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; -#endif - - if (!one_process) { - ap_fatal_signal_setup(ap_server_conf, pconf); - } - -#ifndef NO_USE_SIGACTION - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGTERM)"); -#ifdef SIGINT - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGINT)"); -#endif -#ifdef SIGXCPU - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXCPU, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXCPU)"); -#endif -#ifdef SIGXFSZ - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXFSZ, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXFSZ)"); -#endif -#ifdef SIGPIPE - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGPIPE)"); -#endif - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -#else - if (!one_process) { -#ifdef SIGXCPU - apr_signal(SIGXCPU, SIG_DFL); -#endif /* SIGXCPU */ -#ifdef SIGXFSZ - apr_signal(SIGXFSZ, SIG_DFL); -#endif /* SIGXFSZ */ - } - - apr_signal(SIGTERM, sig_term); -#ifdef SIGHUP - apr_signal(SIGHUP, restart); -#endif /* SIGHUP */ -#ifdef AP_SIG_GRACEFUL - apr_signal(AP_SIG_GRACEFUL, restart); -#endif /* AP_SIG_GRACEFUL */ -#ifdef SIGPIPE - apr_signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - -#endif -} - -/***************************************************************** - * Here follows a long bunch of generic server bookkeeping stuff... - */ - -int ap_graceful_stop_signalled(void) - /* XXX this is really a bad confusing obsolete name - * maybe it should be ap_mpm_process_exiting? - */ -{ - return workers_may_exit; -} - -/***************************************************************** - * Child process main loop. - */ - -static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, - int my_thread_num, apr_bucket_alloc_t *bucket_alloc) -{ - conn_rec *current_conn; - long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); - int csd; - ap_sb_handle_t *sbh; - - ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); - apr_os_sock_get(&csd, sock); - - current_conn = ap_run_create_connection(p, ap_server_conf, sock, - conn_id, sbh, bucket_alloc); - if (current_conn) { - ap_process_connection(current_conn, sock); - ap_lingering_close(current_conn); - } -} - -/* requests_this_child has gone to zero or below. See if the admin coded - "MaxRequestsPerChild 0", and keep going in that case. Doing it this way - simplifies the hot path in worker_thread */ -static void check_infinite_requests(void) -{ - if (ap_max_requests_per_child) { - signal_threads(ST_GRACEFUL); - } - else { - /* wow! if you're executing this code, you may have set a record. - * either this child process has served over 2 billion requests, or - * you're running a threaded 2.0 on a 16 bit machine. - * - * I'll buy pizza and beers at Apachecon for the first person to do - * the former without cheating (dorking with INT_MAX, or running with - * uncommitted performance patches, for example). - * - * for the latter case, you probably deserve a beer too. Greg Ames - */ - - requests_this_child = INT_MAX; /* keep going */ - } -} - -static void unblock_signal(int sig) -{ - sigset_t sig_mask; - - sigemptyset(&sig_mask); - sigaddset(&sig_mask, sig); -#if defined(SIGPROCMASK_SETS_THREAD_MASK) - sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); -#else - pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); -#endif -} - -static void *worker_thread(apr_thread_t *thd, void * dummy) -{ - proc_info * ti = dummy; - int process_slot = ti->pid; - int thread_slot = ti->tid; - apr_uint32_t my_worker_num = (apr_uint32_t)(ti->tid); - apr_pool_t *tpool = apr_thread_pool_get(thd); - void *csd = NULL; - apr_allocator_t *allocator; - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - apr_bucket_alloc_t *bucket_alloc; - int n; - apr_pollfd_t *pollset; - apr_status_t rv; - ap_listen_rec *lr, *last_lr = ap_listeners; - int is_listener; - - ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); - - free(ti); - - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - /* XXX: why is ptrans's parent not tpool? --jcw 08/2003 */ - apr_pool_create_ex(&ptrans, NULL, NULL, allocator); - apr_allocator_owner_set(allocator, ptrans); - bucket_alloc = apr_bucket_alloc_create_ex(allocator); - - apr_poll_setup(&pollset, num_listensocks, tpool); - for(lr = ap_listeners ; lr != NULL ; lr = lr->next) - apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); - - /* TODO: Switch to a system where threads reuse the results from earlier - poll calls - manoj */ - is_listener = 0; - while (!workers_may_exit) { - - ap_update_child_status_from_indexes(process_slot, thread_slot, - SERVER_READY, NULL); - if (!is_listener) { - /* Wait until it's our turn to become the listener */ - if ((rv = worker_stack_wait(idle_worker_stack, my_worker_num)) != - APR_SUCCESS) { - if (rv != APR_EINVAL) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "worker_stack_wait failed. Shutting down"); - } - break; - } - if (workers_may_exit) { - break; - } - is_listener = 1; - } - - /* TODO: requests_this_child should be synchronized - aaron */ - if (requests_this_child <= 0) { - check_infinite_requests(); - } - if (workers_may_exit) break; - - if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (workers_may_exit) { - break; - } - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_lock failed. Attempting to shutdown " - "process gracefully."); - signal_threads(ST_GRACEFUL); - break; /* skip the lock release */ - } - - if (!ap_listeners->next) { - /* Only one listener, so skip the poll */ - lr = ap_listeners; - } - else { - while (!workers_may_exit) { - apr_status_t ret; - apr_int16_t event; - - ret = apr_poll(pollset, num_listensocks, &n, -1); - if (ret != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(ret)) { - continue; - } - - /* apr_poll() will only return errors in catastrophic - * circumstances. Let's try exiting gracefully, for now. */ - ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) - ap_server_conf, "apr_poll: (listen)"); - signal_threads(ST_GRACEFUL); - } - - if (workers_may_exit) break; - - /* find a listener */ - lr = last_lr; - do { - lr = lr->next; - if (lr == NULL) { - lr = ap_listeners; - } - /* XXX: Should we check for POLLERR? */ - apr_poll_revents_get(&event, lr->sd, pollset); - if (event & APR_POLLIN) { - last_lr = lr; - goto got_fd; - } - } while (lr != last_lr); - } - } - got_fd: - if (!workers_may_exit) { - rv = lr->accept_func(&csd, lr, ptrans); - /* later we trash rv and rely on csd to indicate success/failure */ - AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd); - - if (rv == APR_EGENERAL) { - /* E[NM]FILE, ENOMEM, etc */ - resource_shortage = 1; - signal_threads(ST_GRACEFUL); - } - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (workers_may_exit) { - break; - } - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - } - if (csd != NULL) { - is_listener = 0; - worker_stack_awaken_next(idle_worker_stack); - process_socket(ptrans, csd, process_slot, - thread_slot, bucket_alloc); - apr_pool_clear(ptrans); - requests_this_child--; - } - if ((ap_mpm_pod_check(pod) == APR_SUCCESS) || - (ap_my_generation != - ap_scoreboard_image->global->running_generation)) { - signal_threads(ST_GRACEFUL); - break; - } - } - else { - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - } - break; - } - } - - dying = 1; - ap_scoreboard_image->parent[process_slot].quiescing = 1; - - worker_stack_term(idle_worker_stack); - - ap_update_child_status_from_indexes(process_slot, thread_slot, - (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); - - apr_bucket_alloc_destroy(bucket_alloc); - - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -static int check_signal(int signum) -{ - switch (signum) { - case SIGTERM: - case SIGINT: - return 1; - } - return 0; -} - -/* XXX under some circumstances not understood, children can get stuck - * in start_threads forever trying to take over slots which will - * never be cleaned up; for now there is an APLOG_DEBUG message issued - * every so often when this condition occurs - */ -static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) -{ - thread_starter *ts = dummy; - apr_thread_t **threads = ts->threads; - apr_threadattr_t *thread_attr = ts->threadattr; - int child_num_arg = ts->child_num_arg; - int my_child_num = child_num_arg; - proc_info *my_info; - apr_status_t rv; - int i; - int threads_created = 0; - int loops; - int prev_threads_created; - - idle_worker_stack = worker_stack_create(pchild, ap_threads_per_child); - if (idle_worker_stack == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, - "worker_stack_create() failed"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - worker_wakeups = (worker_wakeup_info **) - apr_palloc(pchild, sizeof(worker_wakeup_info *) * - ap_threads_per_child); - - loops = prev_threads_created = 0; - while (1) { - for (i = 0; i < ap_threads_per_child; i++) { - int status = ap_scoreboard_image->servers[child_num_arg][i].status; - worker_wakeup_info *wakeup; - - if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { - continue; - } - - wakeup = worker_wakeup_create(pchild); - if (wakeup == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0, - ap_server_conf, "worker_wakeup_create failed"); - clean_child_exit(APEXIT_CHILDFATAL); - } - worker_wakeups[threads_created] = wakeup; - my_info = (proc_info *)malloc(sizeof(proc_info)); - if (my_info == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - my_info->pid = my_child_num; - my_info->tid = i; - my_info->sd = 0; - - /* We are creating threads right now */ - ap_update_child_status_from_indexes(my_child_num, i, - SERVER_STARTING, NULL); - /* We let each thread update its own scoreboard entry. This is - * done because it lets us deal with tid better. - */ - rv = apr_thread_create(&threads[i], thread_attr, - worker_thread, my_info, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again if we exit. */ - apr_sleep(10 * APR_USEC_PER_SEC); - clean_child_exit(APEXIT_CHILDFATAL); - } - threads_created++; - } - if (start_thread_may_exit || threads_created == ap_threads_per_child) { - break; - } - /* wait for previous generation to clean up an entry */ - apr_sleep(1 * APR_USEC_PER_SEC); - ++loops; - if (loops % 120 == 0) { /* every couple of minutes */ - if (prev_threads_created == threads_created) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "child %" APR_PID_T_FMT " isn't taking over " - "slots very quickly (%d of %d)", - ap_my_pid, threads_created, ap_threads_per_child); - } - prev_threads_created = threads_created; - } - } - - /* What state should this child_main process be listed as in the - * scoreboard...? - * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, - * (request_rec *) NULL); - * - * This state should be listed separately in the scoreboard, in some kind - * of process_status, not mixed in with the worker threads' status. - * "life_status" is almost right, but it's in the worker's structure, and - * the name could be clearer. gla - */ - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -static void join_workers(apr_thread_t **threads) -{ - int i; - apr_status_t rv, thread_rv; - - for (i = 0; i < ap_threads_per_child; i++) { - if (threads[i]) { /* if we ever created this thread */ - rv = apr_thread_join(&thread_rv, threads[i]); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join worker " - "thread %d", - i); - } - } - } -} - -static void join_start_thread(apr_thread_t *start_thread_id) -{ - apr_status_t rv, thread_rv; - - start_thread_may_exit = 1; /* tell it to give up in case it is still - * trying to take over slots from a - * previous generation - */ - rv = apr_thread_join(&thread_rv, start_thread_id); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join the start " - "thread"); - } -} - -static void child_main(int child_num_arg) -{ - apr_thread_t **threads; - apr_status_t rv; - thread_starter *ts; - apr_threadattr_t *thread_attr; - apr_thread_t *start_thread_id; - - mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this - * child initializes - */ - - ap_my_pid = getpid(); - ap_fatal_signal_child_setup(ap_server_conf); - apr_pool_create(&pchild, pconf); - - /*stuff to do before we switch id's, so we have permissions.*/ - ap_reopen_scoreboard(pchild, NULL, 0); - - rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, - pchild)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize cross-process lock in child"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (unixd_setup_child()) { - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_run_child_init(pchild, ap_server_conf); - - /* done with init critical section */ - - /* Just use the standard apr_setup_signal_thread to block all signals - * from being received. The child processes no longer use signals for - * any communication with the parent process. - */ - rv = apr_setup_signal_thread(); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize signal thread"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (ap_max_requests_per_child) { - requests_this_child = ap_max_requests_per_child; - } - else { - /* coding a value of zero means infinity */ - requests_this_child = INT_MAX; - } - - /* Setup worker threads */ - - /* clear the storage; we may not create all our threads immediately, - * and we want a 0 entry to indicate a thread which was not created - */ - threads = (apr_thread_t **)calloc(1, - sizeof(apr_thread_t *) * ap_threads_per_child); - if (threads == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts)); - - apr_threadattr_create(&thread_attr, pchild); - /* 0 means PTHREAD_CREATE_JOINABLE */ - apr_threadattr_detach_set(thread_attr, 0); - - ts->threads = threads; - ts->child_num_arg = child_num_arg; - ts->threadattr = thread_attr; - - rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, - ts, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again if we exit. */ - apr_sleep(10 * APR_USEC_PER_SEC); - clean_child_exit(APEXIT_CHILDFATAL); - } - - mpm_state = AP_MPMQ_RUNNING; - - /* If we are only running in one_process mode, we will want to - * still handle signals. */ - if (one_process) { - /* Block until we get a terminating signal. */ - apr_signal_thread(check_signal); - /* make sure the start thread has finished; signal_threads() - * and join_workers() depend on that - */ - /* XXX join_start_thread() won't be awakened if one of our - * threads encounters a critical error and attempts to - * shutdown this child - */ - join_start_thread(start_thread_id); - signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more - * quickly than the dispatch of the signal thread - * beats the Pipe of Death and the browsers - */ - /* A terminating signal was received. Now join each of the - * workers to clean them up. - * If the worker already exited, then the join frees - * their resources and returns. - * If the worker hasn't exited, then this blocks until - * they have (then cleans up). - */ - join_workers(threads); - } - else { /* !one_process */ - /* remove SIGTERM from the set of blocked signals... if one of - * the other threads in the process needs to take us down - * (e.g., for MaxRequestsPerChild) it will send us SIGTERM - */ - unblock_signal(SIGTERM); - join_start_thread(start_thread_id); - join_workers(threads); - } - - free(threads); - - clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); -} - -static int make_child(server_rec *s, int slot) -{ - int pid; - - if (slot + 1 > ap_max_daemons_limit) { - ap_max_daemons_limit = slot + 1; - } - - if (one_process) { - set_signals(); - ap_scoreboard_image->parent[slot].pid = getpid(); - child_main(slot); - } - - if ((pid = fork()) == -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, - "fork: Unable to fork new process"); - - /* fork didn't succeed. Fix the scoreboard or else - * it will say SERVER_STARTING forever and ever - */ - ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); - - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again. */ - apr_sleep(10 * APR_USEC_PER_SEC); - - return -1; - } - - if (!pid) { -#ifdef HAVE_BINDPROCESSOR - /* By default, AIX binds to a single processor. This bit unbinds - * children which will then bind to another CPU. - */ - int status = bindprocessor(BINDPROCESS, (int)getpid(), - PROCESSOR_CLASS_ANY); - if (status != OK) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, - ap_server_conf, - "processor unbind failed %d", status); -#endif - RAISE_SIGSTOP(MAKE_CHILD); - - apr_signal(SIGTERM, just_die); - child_main(slot); - - clean_child_exit(0); - } - /* else */ - ap_scoreboard_image->parent[slot].quiescing = 0; - ap_scoreboard_image->parent[slot].pid = pid; - return 0; -} - -/* start up a bunch of children */ -static void startup_children(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->parent[i].pid != 0) { - continue; - } - if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; - } -} - - -/* - * idle_spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough idle servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int idle_spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (32) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_idle_server_maintenance(void) -{ - int i, j; - int idle_thread_count; - worker_score *ws; - process_score *ps; - int free_length; - int totally_free_length = 0; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead; - int total_non_dead; - - /* initialize the free_list */ - free_length = 0; - - idle_thread_count = 0; - last_non_dead = -1; - total_non_dead = 0; - - for (i = 0; i < ap_daemons_limit; ++i) { - /* Initialization to satisfy the compiler. It doesn't know - * that ap_threads_per_child is always > 0 */ - int status = SERVER_DEAD; - int any_dying_threads = 0; - int any_dead_threads = 0; - int all_dead_threads = 1; - - if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate) - break; - ps = &ap_scoreboard_image->parent[i]; - for (j = 0; j < ap_threads_per_child; j++) { - ws = &ap_scoreboard_image->servers[i][j]; - status = ws->status; - - /* XXX any_dying_threads is probably no longer needed GLA */ - any_dying_threads = any_dying_threads || - (status == SERVER_GRACEFUL); - any_dead_threads = any_dead_threads || (status == SERVER_DEAD); - all_dead_threads = all_dead_threads && - (status == SERVER_DEAD || - status == SERVER_GRACEFUL); - - /* We consider a starting server as idle because we started it - * at least a cycle ago, and if it still hasn't finished starting - * then we're just going to swamp things worse by forking more. - * So we hopefully won't need to fork more if we count it. - * This depends on the ordering of SERVER_READY and SERVER_STARTING. - */ - if (status <= SERVER_READY && status != SERVER_DEAD && - !ps->quiescing && - ps->generation == ap_my_generation && - /* XXX the following shouldn't be necessary if we clean up - * properly after seg faults, but we're not yet GLA - */ - ps->pid != 0) { - ++idle_thread_count; - } - } - if (any_dead_threads && totally_free_length < idle_spawn_rate - && (!ps->pid /* no process in the slot */ - || ps->quiescing)) { /* or at least one is going away */ - if (all_dead_threads) { - /* great! we prefer these, because the new process can - * start more threads sooner. So prioritize this slot - * by putting it ahead of any slots with active threads. - * - * first, make room by moving a slot that's potentially still - * in use to the end of the array - */ - free_slots[free_length] = free_slots[totally_free_length]; - free_slots[totally_free_length++] = i; - } - else { - /* slot is still in use - back of the bus - */ - free_slots[free_length] = i; - } - ++free_length; - } - /* XXX if (!ps->quiescing) is probably more reliable GLA */ - if (!any_dying_threads) { - last_non_dead = i; - ++total_non_dead; - } - } - ap_max_daemons_limit = last_non_dead + 1; - - if (idle_thread_count > max_spare_threads) { - /* Kill off one child */ - ap_mpm_pod_signal(pod); - idle_spawn_rate = 1; - } - else if (idle_thread_count < min_spare_threads) { - /* terminate the free list */ - if (free_length == 0) { - /* only report this condition once */ - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, - ap_server_conf, - "server reached MaxClients setting, consider" - " raising the MaxClients setting"); - reported = 1; - } - idle_spawn_rate = 1; - } - else { - if (free_length > idle_spawn_rate) { - free_length = idle_spawn_rate; - } - if (idle_spawn_rate >= 8) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "server seems busy, (you may need " - "to increase StartServers, ThreadsPerChild " - "or Min/MaxSpareThreads), " - "spawning %d children, there are around %d idle " - "threads, and %d total children", free_length, - idle_thread_count, total_non_dead); - } - for (i = 0; i < free_length; ++i) { - make_child(ap_server_conf, free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } - else if (idle_spawn_rate < MAX_SPAWN_RATE) { - idle_spawn_rate *= 2; - } - } - } - else { - idle_spawn_rate = 1; - } -} - -static void server_main_loop(int remaining_children_to_start) -{ - int child_slot; - apr_exit_why_e exitwhy; - int status, processed_status; - apr_proc_t pid; - int i; - - while (!restart_pending && !shutdown_pending) { - ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); - - if (pid.pid != -1) { - processed_status = ap_process_child_status(&pid, exitwhy, status); - if (processed_status == APEXIT_CHILDFATAL) { - shutdown_pending = 1; - child_fatal = 1; - return; - } - /* non-fatal death... note that it's gone in the scoreboard. */ - child_slot = find_child_by_pid(&pid); - if (child_slot >= 0) { - for (i = 0; i < ap_threads_per_child; i++) - ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); - - ap_scoreboard_image->parent[child_slot].pid = 0; - ap_scoreboard_image->parent[child_slot].quiescing = 0; - if (processed_status == APEXIT_CHILDSICK) { - /* resource shortage, minimize the fork rate */ - idle_spawn_rate = 1; - } - else if (remaining_children_to_start - && child_slot < ap_daemons_limit) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - make_child(ap_server_conf, child_slot); - --remaining_children_to_start; - } -#if APR_HAS_OTHER_CHILD - } - else if (apr_proc_other_child_read(&pid, status) == 0) { - /* handled */ -#endif - } - else if (is_graceful) { - /* Great, we've probably just lost a slot in the - * scoreboard. Somehow we don't know about this child. - */ - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, - ap_server_conf, - "long lost child came home! (pid %ld)", - (long)pid.pid); - } - /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ - continue; - } - else if (remaining_children_to_start) { - /* we hit a 1 second timeout in which none of the previous - * generation of children needed to be reaped... so assume - * they're all done, and pick up the slack if any is left. - */ - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - /* In any event we really shouldn't do the code below because - * few of the servers we just started are in the IDLE state - * yet, so we'd mistakenly create an extra server. - */ - continue; - } - - perform_idle_server_maintenance(); - } -} - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - int remaining_children_to_start; - apr_status_t rv; - - ap_log_pid(pconf, ap_pid_fname); - - first_server_limit = server_limit; - first_thread_limit = thread_limit; - if (changed_limit_at_restart) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "WARNING: Attempt to change ServerLimit or ThreadLimit " - "ignored during restart"); - changed_limit_at_restart = 0; - } - - /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, - ap_server_root_relative(_pconf, ap_lock_fname), - ap_my_pid); - - rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, - ap_accept_lock_mech, _pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - -#if APR_USE_SYSVSEM_SERIALIZE - if (ap_accept_lock_mech == APR_LOCK_DEFAULT || - ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#else - if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#endif - rv = unixd_set_proc_mutex_perms(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't set permissions on cross-process lock; " - "check User and Group directives"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - } - - if (!is_graceful) { - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - /* fix the generation number in the global score; we just got a new, - * cleared scoreboard - */ - ap_scoreboard_image->global->running_generation = ap_my_generation; - } - - set_signals(); - /* Don't thrash... */ - if (max_spare_threads < min_spare_threads + ap_threads_per_child) - max_spare_threads = min_spare_threads + ap_threads_per_child; - - /* If we're doing a graceful_restart then we're going to see a lot - * of children exiting immediately when we get into the main loop - * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty - * rapidly... and for each one that exits we'll start a new one until - * we reach at least daemons_min_free. But we may be permitted to - * start more than that, so we'll just keep track of how many we're - * supposed to start up without the 1 second penalty between each fork. - */ - remaining_children_to_start = ap_daemons_to_start; - if (remaining_children_to_start > ap_daemons_limit) { - remaining_children_to_start = ap_daemons_limit; - } - if (!is_graceful) { - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - } - else { - /* give the system some time to recover before kicking into - * exponential mode */ - hold_off_on_exponential_spawning = 10; - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(accept_mutex), - apr_proc_mutex_defname()); -#endif - restart_pending = shutdown_pending = 0; - mpm_state = AP_MPMQ_RUNNING; - - server_main_loop(remaining_children_to_start); - mpm_state = AP_MPMQ_STOPPING; - - if (shutdown_pending) { - /* Time to gracefully shut down: - * Kill child processes, tell them to call child_exit, etc... - * (By "gracefully" we don't mean graceful in the same sense as - * "apachectl graceful" where we allow old connections to finish.) - */ - if (unixd_killpg(getpgrp(), SIGTERM) < 0) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM"); - } - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - - if (!child_fatal) { - /* cleanup pid file on normal shutdown */ - const char *pidfile = NULL; - pidfile = ap_server_root_relative (pconf, ap_pid_fname); - if ( pidfile != NULL && unlink(pidfile) == 0) - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "removed PID file %s (pid=%ld)", - pidfile, (long)getpid()); - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, - ap_server_conf, "caught SIGTERM, shutting down"); - } - return 1; - } - - /* we've been told to restart */ - apr_signal(SIGHUP, SIG_IGN); - - if (one_process) { - /* not worth thinking about */ - return 1; - } - - /* advance to the next generation */ - /* XXX: we really need to make sure this new generation number isn't in - * use by any of the children. - */ - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - - if (is_graceful) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); - /* wake up the children...time to die. But we'll have more soon */ - ap_mpm_pod_killpg(pod, ap_daemons_limit); - - - /* This is mostly for debugging... so that we know what is still - * gracefully dealing with existing request. - */ - - } - else { - /* Kill 'em all. Since the child acts the same on the parents SIGTERM - * and a SIGHUP, we may as well use the same signal, because some user - * pthreads are stealing signals from us left and right. - */ - ap_mpm_pod_killpg(pod, ap_daemons_limit); - - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "SIGHUP received. Attempting to restart"); - } - - return 0; -} - -/* This really should be a post_config hook, but the error log is already - * redirected by that point, so we need to do this in the open_logs phase. - */ -static int leader_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - apr_status_t rv; - - pconf = p; - ap_server_conf = s; - - if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, - NULL, "no listening sockets available, shutting down"); - return DONE; - } - - if (!one_process) { - if ((rv = ap_mpm_pod_open(pconf, &pod))) { - ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, - "Could not open pipe-of-death."); - return DONE; - } - } - return OK; -} - -static int leader_pre_config(apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp) -{ - static int restart_num = 0; - int no_detach, debug, foreground; - ap_directive_t *pdir; - ap_directive_t *max_clients = NULL; - apr_status_t rv; - - mpm_state = AP_MPMQ_STARTING; - - /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ - for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { - if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { - if (!max_clients) { - break; /* we're in the clear, got ThreadsPerChild first */ - } - else { - /* now to swap the data */ - ap_directive_t temp; - - temp.directive = pdir->directive; - temp.args = pdir->args; - /* Make sure you don't change 'next', or you may get loops! */ - /* XXX: first_child, parent, and data can never be set - * for these directives, right? -aaron */ - temp.filename = pdir->filename; - temp.line_num = pdir->line_num; - - pdir->directive = max_clients->directive; - pdir->args = max_clients->args; - pdir->filename = max_clients->filename; - pdir->line_num = max_clients->line_num; - - max_clients->directive = temp.directive; - max_clients->args = temp.args; - max_clients->filename = temp.filename; - max_clients->line_num = temp.line_num; - break; - } - } - else if (!max_clients - && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { - max_clients = pdir; - } - } - - debug = ap_exists_config_define("DEBUG"); - - if (debug) { - foreground = one_process = 1; - no_detach = 0; - } - else { - one_process = ap_exists_config_define("ONE_PROCESS"); - no_detach = ap_exists_config_define("NO_DETACH"); - foreground = ap_exists_config_define("FOREGROUND"); - } - - /* sigh, want this only the second time around */ - if (restart_num++ == 1) { - is_graceful = 0; - - if (!one_process && !foreground) { - rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND - : APR_PROC_DETACH_DAEMONIZE); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "apr_proc_detach failed"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - parent_pid = ap_my_pid = getpid(); - } - - unixd_pre_config(ptemp); - ap_listen_pre_config(); - ap_daemons_to_start = DEFAULT_START_DAEMON; - min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; - max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; - ap_daemons_limit = server_limit; - ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; - ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - return OK; -} - -static void leader_hooks(apr_pool_t *p) -{ - /* The leader open_logs phase must run before the core's, or stderr - * will be redirected to a file, and the messages won't print to the - * console. - */ - static const char *const aszSucc[] = {"core.c", NULL}; - one_process = 0; - - ap_hook_open_logs(leader_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); - /* we need to set the MPM state before other pre-config hooks use MPM query - * to retrieve it, so register as REALLY_FIRST - */ - ap_hook_pre_config(leader_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); -} - -static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_to_start = atoi(arg); - return NULL; -} - -static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - min_spare_threads = atoi(arg); - if (min_spare_threads <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - min_spare_threads = 1; - } - - return NULL; -} - -static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - max_spare_threads = atoi(arg); - return NULL; -} - -static const char *set_max_clients (cmd_parms *cmd, void *dummy, - const char *arg) -{ - int max_clients; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - /* It is ok to use ap_threads_per_child here because we are - * sure that it gets set before MaxClients in the pre_config stage. */ - max_clients = atoi(arg); - if (max_clients < ap_threads_per_child) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients (%d) must be at least as large", - max_clients); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " large as ThreadsPerChild (%d). Automatically", - ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " increasing MaxClients to %d.", - ap_threads_per_child); - max_clients = ap_threads_per_child; - } - ap_daemons_limit = max_clients / ap_threads_per_child; - if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients (%d) is not an integer multiple", - max_clients); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " of ThreadsPerChild (%d), lowering MaxClients to %d", - ap_threads_per_child, - ap_daemons_limit * ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " for a maximum of %d child processes,", - ap_daemons_limit); - max_clients = ap_daemons_limit * ap_threads_per_child; - } - if (ap_daemons_limit > server_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients of %d would require %d servers,", - max_clients, ap_daemons_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " and would exceed the ServerLimit value of %d.", - server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " Automatically lowering MaxClients to %d. To increase,", - server_limit * ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " please see the ServerLimit directive."); - ap_daemons_limit = server_limit; - } - else if (ap_daemons_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require MaxClients > 0, setting to 1"); - ap_daemons_limit = 1; - } - return NULL; -} - -static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_per_child = atoi(arg); - if (ap_threads_per_child > thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " - "value of %d", ap_threads_per_child, - thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "threads, lowering ThreadsPerChild to %d. To increase, please" - " see the", thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " ThreadLimit directive."); - ap_threads_per_child = thread_limit; - } - else if (ap_threads_per_child < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadsPerChild > 0, setting to 1"); - ap_threads_per_child = 1; - } - return NULL; -} - -static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_server_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_server_limit = atoi(arg); - /* you cannot change ServerLimit across a restart; ignore - * any such attempts - */ - if (first_server_limit && - tmp_server_limit != server_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - server_limit = tmp_server_limit; - - if (server_limit > MAX_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ServerLimit of %d exceeds compile time limit " - "of %d servers,", server_limit, MAX_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); - server_limit = MAX_SERVER_LIMIT; - } - else if (server_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ServerLimit > 0, setting to 1"); - server_limit = 1; - } - return NULL; -} - -static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_thread_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_thread_limit = atoi(arg); - /* you cannot change ThreadLimit across a restart; ignore - * any such attempts - */ - if (first_thread_limit && - tmp_thread_limit != thread_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - thread_limit = tmp_thread_limit; - - if (thread_limit > MAX_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadLimit of %d exceeds compile time limit " - "of %d servers,", thread_limit, MAX_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); - thread_limit = MAX_THREAD_LIMIT; - } - else if (thread_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadLimit > 0, setting to 1"); - thread_limit = 1; - } - return NULL; -} - -static const command_rec leader_cmds[] = { -UNIX_DAEMON_COMMANDS, -LISTEN_COMMANDS, -AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, - "Number of child processes launched at server startup"), -AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, - "Minimum number of idle children, to handle request spikes"), -AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, - "Maximum number of idle children"), -AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, - "Maximum number of children alive at the same time"), -AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, - "Number of threads each child creates"), -AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, - "Maximum value of MaxClients for this run of Apache"), -AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, - "Maximum worker threads in a server for this run of Apache"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_leader_module = { - MPM20_MODULE_STUFF, - ap_mpm_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - leader_cmds, /* command apr_table_t */ - leader_hooks /* register_hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/mpm.h deleted file mode 100644 index 1db1d1d0..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/mpm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "scoreboard.h" -#include "unixd.h" - -#ifndef APACHE_MPM_LEADER_H -#define APACHE_MPM_LEADER_H - -#define LEADER_MPM - -#define MPM_NAME "Leader-Follower" - -#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -#define AP_MPM_WANT_WAIT_OR_TIMEOUT -#define AP_MPM_WANT_PROCESS_CHILD_STATUS -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_LOCKFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -#define AP_MPM_WANT_SIGNAL_SERVER -#define AP_MPM_WANT_SET_MAX_MEM_FREE -#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER -#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK - -#define AP_MPM_USES_POD 1 -#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) -#define MPM_ACCEPT_FUNC unixd_accept - -extern int ap_threads_per_child; -extern int ap_max_daemons_limit; -extern server_rec *ap_server_conf; -extern char ap_coredump_dir[MAX_STRING_LEN]; - -#endif /* APACHE_MPM_LEADER_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/mpm_default.h deleted file mode 100644 index d5a33989..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/leader/mpm_default.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of servers to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_DAEMON -#define DEFAULT_START_DAEMON 3 -#endif - -/* Maximum number of *free* server processes --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_FREE_DAEMON -#define DEFAULT_MAX_FREE_DAEMON 10 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_FREE_DAEMON -#define DEFAULT_MIN_FREE_DAEMON 3 -#endif - -#ifndef DEFAULT_THREADS_PER_CHILD -#define DEFAULT_THREADS_PER_CHILD 25 -#endif - -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/Makefile.in deleted file mode 100644 index 374f1306..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libperchild.la -LTLIBRARY_SOURCES = perchild.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/config5.m4 b/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/config5.m4 deleted file mode 100644 index 368052f5..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/config5.m4 +++ /dev/null @@ -1,6 +0,0 @@ -dnl ## XXX - Need a more thorough check of the proper flags to use - -if test "$MPM_NAME" = "perchild" ; then - AC_CHECK_FUNCS(pthread_kill) - APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/mpm.h deleted file mode 100644 index 84e808db..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/mpm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "httpd.h" -#include "mpm_default.h" -#include "unixd.h" - -#ifndef APACHE_MPM_PERCHILD_H -#define APACHE_MPM_PERCHILD_H - -#define PERCHILD_MPM - -#define MPM_NAME "Perchild" - -#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -#define AP_MPM_WANT_WAIT_OR_TIMEOUT -#define AP_MPM_WANT_PROCESS_CHILD_STATUS -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_LOCKFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -#define AP_MPM_WANT_SIGNAL_SERVER -#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER -#define AP_MPM_USES_POD - -#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) -#define MPM_ACCEPT_FUNC unixd_accept - -/* Table of child status */ -#define SERVER_DEAD 0 -#define SERVER_DYING 1 -#define SERVER_ALIVE 2 - -typedef struct ap_ctable{ - pid_t pid; - unsigned char status; -} ap_ctable; - -extern int ap_threads_per_child; -extern int ap_max_daemons_limit; -extern server_rec *ap_server_conf; - -#endif /* APACHE_MPM_PERCHILD_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/mpm_default.h deleted file mode 100644 index ece876b5..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/mpm_default.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of threads to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_THREAD -#define DEFAULT_START_THREAD 5 -#endif - -/* Maximum number of *free* server threads --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_SPARE_THREAD -#define DEFAULT_MAX_SPARE_THREAD 10 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_SPARE_THREAD -#define DEFAULT_MIN_SPARE_THREAD 5 -#endif - -/* Number of servers to spawn off by default - */ -#ifndef DEFAULT_NUM_DAEMON -#define DEFAULT_NUM_DAEMON 2 -#endif - -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/perchild.c b/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/perchild.c deleted file mode 100644 index 8b205beb..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/perchild/perchild.c +++ /dev/null @@ -1,2045 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_hash.h" -#include "apr_strings.h" -#include "apr_pools.h" -#include "apr_portable.h" -#include "apr_file_io.h" -#include "apr_signal.h" - -#define APR_WANT_IOVEC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#if !APR_HAS_THREADS -#error The perchild MPM requires APR threads, but they are unavailable. -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_protocol.h" -#include "http_connection.h" -#include "ap_mpm.h" -#include "unixd.h" -#include "mpm_common.h" -#include "ap_listen.h" -#include "mpm_default.h" -#include "mpm.h" -#include "scoreboard.h" -#include "util_filter.h" -#include "apr_poll.h" - -#ifdef HAVE_POLL_H -#include <poll.h> -#endif -#ifdef HAVE_SYS_POLL_H -#include <sys/poll.h> -#endif - -/* ### should be APR-ized */ -#include <grp.h> -#include <pwd.h> -#include <sys/stat.h> -#include <sys/un.h> -#include <setjmp.h> -#ifdef HAVE_SYS_PROCESSOR_H -#include <sys/processor.h> /* for bindprocessor() */ -#endif - -/* - * Define some magic numbers that we use for the state of the incomming - * request. These must be < 0 so they don't collide with a file descriptor. - */ -#define AP_PERCHILD_THISCHILD -1 -#define AP_PERCHILD_OTHERCHILD -2 - -/* Limit on the threads per process. Clients will be locked out if more than - * this * server_limit are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_THREAD_LIMIT -#define DEFAULT_THREAD_LIMIT 64 -#endif - -/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_THREAD_LIMIT -#define MAX_THREAD_LIMIT 20000 -#endif - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_SERVER_LIMIT -#define DEFAULT_SERVER_LIMIT 8 -#endif - -/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_SERVER_LIMIT -#define MAX_SERVER_LIMIT 20000 -#endif - -/* - * Actual definitions of config globals - */ - -static int threads_to_start = 0; /* Worker threads per child */ -static int min_spare_threads = 0; -static int max_spare_threads = 0; -static int max_threads = 0; -static int server_limit = DEFAULT_SERVER_LIMIT; -static int first_server_limit; -static int thread_limit = DEFAULT_THREAD_LIMIT; -static int first_thread_limit; -static int changed_limit_at_restart; -static int num_daemons = 0; -static int curr_child_num = 0; -static int workers_may_exit = 0; -static int requests_this_child; -static int num_listensocks = 0; -static ap_pod_t *pod; -static jmp_buf jmpbuffer; - -struct child_info_t { - uid_t uid; - gid_t gid; - int input; /* The socket descriptor */ - int output; /* The socket descriptor */ -}; - -typedef struct { - const char *sockname; /* The base name for the socket */ - const char *fullsockname; /* socket base name + extension */ - int input; /* The socket descriptor */ - int output; /* The socket descriptor */ -} perchild_server_conf; - -typedef struct child_info_t child_info_t; - -/* Tables used to determine the user and group each child process should - * run as. The hash table is used to correlate a server name with a child - * process. - */ -static child_info_t *child_info_table; -static int *thread_socket_table; -struct ap_ctable *ap_child_table; - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with NumServers changes across AP_SIG_GRACEFUL restarts. We - * use this value to optimize routines that have to scan the entire child - * table. - * - * XXX - It might not be worth keeping this code in. There aren't very - * many child processes in this MPM. - */ -int ap_max_daemons_limit = -1; -int ap_threads_per_child; /* XXX not part of API! axe it! */ - -module AP_MODULE_DECLARE_DATA mpm_perchild_module; - -static apr_file_t *pipe_of_death_in = NULL; -static apr_file_t *pipe_of_death_out = NULL; -static apr_thread_mutex_t *pipe_of_death_mutex; - -/* *Non*-shared http_main globals... */ - -server_rec *ap_server_conf; - -/* one_process --- debugging mode variable; can be set from the command line - * with the -X flag. If set, this gets you the child_main loop running - * in the process which originally started up (no detach, no make_child), - * which is a pretty nice debugging environment. (You'll get a SIGHUP - * early in standalone_main; just continue through. This is the server - * trying to kill off any child processes which it might have lying - * around --- Apache doesn't keep track of their pids, it just sends - * SIGHUP to the process group, ignoring it in the root process. - * Continue through and you'll be fine.). - */ - -static int one_process = 0; - -#ifdef DEBUG_SIGSTOP -int raise_sigstop_flags; -#endif - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pchild; /* Pool for httpd child stuff */ -static apr_pool_t *thread_pool_parent; /* Parent of per-thread pools */ -static apr_thread_mutex_t *thread_pool_parent_mutex; - -static int child_num; -static unsigned int my_pid; /* Linux getpid() doesn't work except in - main thread. Use this instead */ -/* Keep track of the number of worker threads currently active */ -static int worker_thread_count; -static apr_thread_mutex_t *worker_thread_count_mutex; -static int *worker_thread_free_ids; -static apr_threadattr_t *worker_thread_attr; - -/* Keep track of the number of idle worker threads */ -static int idle_thread_count; -static apr_thread_mutex_t *idle_thread_count_mutex; - -/* Locks for accept serialization */ -#ifdef NO_SERIALIZED_ACCEPT -#define SAFE_ACCEPT(stmt) APR_SUCCESS -#else -#define SAFE_ACCEPT(stmt) (stmt) -static apr_proc_mutex_t *process_accept_mutex; -#endif /* NO_SERIALIZED_ACCEPT */ -static apr_thread_mutex_t *thread_accept_mutex; - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_max_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_STATIC; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = server_limit; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = thread_limit; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = max_threads; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = min_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = max_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = num_daemons; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -/* a clean exit from a child with proper cleanup */ -static void clean_child_exit(int code) -{ - if (pchild) { - apr_pool_destroy(pchild); - } - exit(code); -} - -static void just_die(int sig) -{ - clean_child_exit(0); -} - -/***************************************************************** - * Connection structures and accounting... - */ - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; -static int volatile child_fatal; -/* we don't currently track ap_my_generation, but mod_status - * references it so it must be defined */ -ap_generation_t volatile ap_my_generation=0; - -/* - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at - * functions to initiate shutdown or restart without relying on signals. - * Previously this was initiated in sig_term() and restart() signal handlers, - * but we want to be able to start a shutdown/restart from other sources -- - * e.g. on Win32, from the service manager. Now the service manager can - * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that - * these functions can also be called by the child processes, since global - * variables are no longer used to pass on the required action to the parent. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. - */ - -static void ap_start_shutdown(void) -{ - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; -} - -/* do a graceful restart if graceful == 1 */ -static void ap_start_restart(int graceful) -{ - - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = graceful; -} - -static void sig_term(int sig) -{ - ap_start_shutdown(); -} - -static void restart(int sig) -{ -#ifndef WIN32 - ap_start_restart(sig == AP_SIG_GRACEFUL); -#else - ap_start_restart(1); -#endif -} - -static void set_signals(void) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; -#endif - - if (!one_process) { - ap_fatal_signal_setup(ap_server_conf, pconf); - } - -#ifndef NO_USE_SIGACTION - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGTERM)"); -#ifdef SIGINT - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGINT)"); -#endif -#ifdef SIGXCPU - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXCPU, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXCPU)"); -#endif -#ifdef SIGXFSZ - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXFSZ, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXFSZ)"); -#endif -#ifdef SIGPIPE - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGPIPE)"); -#endif - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -#else - if (!one_process) { -#ifdef SIGXCPU - apr_signal(SIGXCPU, SIG_DFL); -#endif /* SIGXCPU */ -#ifdef SIGXFSZ - apr_signal(SIGXFSZ, SIG_DFL); -#endif /* SIGXFSZ */ - } - - apr_signal(SIGTERM, sig_term); -#ifdef SIGHUP - apr_signal(SIGHUP, restart); -#endif /* SIGHUP */ -#ifdef AP_SIG_GRACEFUL - apr_signal(AP_SIG_GRACEFUL, restart); -#endif /* AP_SIG_GRACEFUL */ -#ifdef SIGPIPE - apr_signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - -#endif -} - -/***************************************************************** - * Here follows a long bunch of generic server bookkeeping stuff... - */ - -int ap_graceful_stop_signalled(void) -{ - /* XXX - Does this really work? - Manoj */ - return is_graceful; -} - -/***************************************************************** - * Child process main loop. - */ - -static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id, - apr_bucket_alloc_t *bucket_alloc) -{ - conn_rec *current_conn; - int csd; - apr_status_t rv; - int thread_num = conn_id % thread_limit; - ap_sb_handle_t *sbh; - - if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get"); - } - - if (thread_socket_table[thread_num] < 0) { - ap_sock_disable_nagle(sock); - } - - ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num); - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, - sbh, bucket_alloc); - if (current_conn) { - ap_process_connection(current_conn, sock); - ap_lingering_close(current_conn); - } -} - -static int perchild_process_connection(conn_rec *c) -{ - ap_filter_t *f; - apr_bucket_brigade *bb; - core_net_rec *net; - - apr_pool_userdata_get((void **)&bb, "PERCHILD_SOCKETS", c->pool); - if (bb != NULL) { - for (f = c->output_filters; f != NULL; f = f->next) { - if (!strcmp(f->frec->name, "core")) { - break; - } - } - if (f != NULL) { - net = f->ctx; - net->in_ctx = apr_palloc(c->pool, sizeof(*net->in_ctx)); - net->in_ctx->b = bb; - } - } - return DECLINED; -} - - -static void *worker_thread(apr_thread_t *, void *); - -/* Starts a thread as long as we're below max_threads */ -static int start_thread(void) -{ - apr_thread_t *thread; - int rc; - - apr_thread_mutex_lock(worker_thread_count_mutex); - if (worker_thread_count < max_threads - 1) { - rc = apr_thread_create(&thread, worker_thread_attr, worker_thread, - &worker_thread_free_ids[worker_thread_count], pchild); - if (rc != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rc, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again if we exit. */ - sleep(10); - workers_may_exit = 1; - apr_thread_mutex_unlock(worker_thread_count_mutex); - return 0; - } - else { - worker_thread_count++; - } - } - else { - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, - ap_server_conf, - "server reached MaxThreadsPerChild setting, " - "consider raising the MaxThreadsPerChild or " - "NumServers settings"); - reported = 1; - } - apr_thread_mutex_unlock(worker_thread_count_mutex); - return 0; - } - apr_thread_mutex_unlock(worker_thread_count_mutex); - return 1; - -} - -/* Sets workers_may_exit if we received a character on the pipe_of_death */ -static apr_status_t check_pipe_of_death(void **csd, ap_listen_rec *lr, - apr_pool_t *ptrans) -{ - apr_thread_mutex_lock(pipe_of_death_mutex); - if (!workers_may_exit) { - int ret; - char pipe_read_char; - apr_size_t n = 1; - - ret = apr_recv(lr->sd, &pipe_read_char, &n); - if (APR_STATUS_IS_EAGAIN(ret)) { - /* It lost the lottery. It must continue to suffer - * through a life of servitude. */ - } - else { - /* It won the lottery (or something else is very - * wrong). Embrace death with open arms. */ - workers_may_exit = 1; - } - } - apr_thread_mutex_unlock(pipe_of_death_mutex); - return APR_SUCCESS; -} - -static apr_status_t receive_from_other_child(void **csd, ap_listen_rec *lr, - apr_pool_t *ptrans) -{ - struct msghdr msg; - struct cmsghdr *cmsg; - char buffer[HUGE_STRING_LEN * 2], *headers, *body; - int headerslen, bodylen; - struct iovec iov; - int ret, dp; - apr_os_sock_t sd; - apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(ptrans); - apr_bucket_brigade *bb = apr_brigade_create(ptrans, alloc); - apr_bucket *bucket; - - apr_os_sock_get(&sd, lr->sd); - - iov.iov_base = buffer; - iov.iov_len = sizeof(buffer); - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - cmsg = apr_palloc(ptrans, sizeof(*cmsg) + sizeof(sd)); - cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sd); - msg.msg_control = cmsg; - msg.msg_controllen = cmsg->cmsg_len; - - ret = recvmsg(sd, &msg, 0); - - memcpy(&dp, CMSG_DATA(cmsg), sizeof(dp)); - - *csd = NULL; /* tell apr_os_sock_put() to allocate new apr_socket_t */ - apr_os_sock_put((apr_socket_t **)csd, &dp, ptrans); - - bucket = apr_bucket_eos_create(alloc); - APR_BRIGADE_INSERT_HEAD(bb, bucket); - bucket = apr_bucket_socket_create(*csd, alloc); - APR_BRIGADE_INSERT_HEAD(bb, bucket); - - body = strchr(iov.iov_base, 0); - if (!body) { - return 1; - } - - body++; - bodylen = strlen(body); - - headers = iov.iov_base; - headerslen = body - headers; - - bucket = apr_bucket_heap_create(body, bodylen, NULL, alloc); - APR_BRIGADE_INSERT_HEAD(bb, bucket); - bucket = apr_bucket_heap_create(headers, headerslen, NULL, alloc); - APR_BRIGADE_INSERT_HEAD(bb, bucket); - - apr_pool_userdata_set(bb, "PERCHILD_SOCKETS", NULL, ptrans); - - return 0; -} - -/* idle_thread_count should be incremented before starting a worker_thread */ - -static void *worker_thread(apr_thread_t *thd, void *arg) -{ - void *csd; - apr_pool_t *tpool; /* Pool for this thread */ - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - volatile int thread_just_started = 1; - int srv; - int thread_num = *((int *) arg); - long conn_id = child_num * thread_limit + thread_num; - apr_pollfd_t *pollset; - apr_status_t rv; - ap_listen_rec *lr, *last_lr = ap_listeners; - int n; - apr_bucket_alloc_t *bucket_alloc; - - apr_thread_mutex_lock(thread_pool_parent_mutex); - apr_pool_create(&tpool, thread_pool_parent); - apr_thread_mutex_unlock(thread_pool_parent_mutex); - apr_pool_create(&ptrans, tpool); - - (void) ap_update_child_status_from_indexes(child_num, thread_num, - SERVER_STARTING, - (request_rec *) NULL); - - bucket_alloc = apr_bucket_alloc_create(apr_thread_pool_get(thd)); - - apr_poll_setup(&pollset, num_listensocks, tpool); - for(lr = ap_listeners; lr != NULL; lr = lr->next) { - int fd; - apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); - - apr_os_sock_get(&fd, lr->sd); - } - - while (!workers_may_exit) { - workers_may_exit |= ((ap_max_requests_per_child != 0) - && (requests_this_child <= 0)); - if (workers_may_exit) break; - if (!thread_just_started) { - apr_thread_mutex_lock(idle_thread_count_mutex); - if (idle_thread_count < max_spare_threads) { - idle_thread_count++; - apr_thread_mutex_unlock(idle_thread_count_mutex); - } - else { - apr_thread_mutex_unlock(idle_thread_count_mutex); - break; - } - } - else { - thread_just_started = 0; - } - - (void) ap_update_child_status_from_indexes(child_num, thread_num, - SERVER_READY, - (request_rec *) NULL); - - apr_thread_mutex_lock(thread_accept_mutex); - if (workers_may_exit) { - apr_thread_mutex_unlock(thread_accept_mutex); - break; - } - if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(process_accept_mutex))) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_proc_mutex_lock failed. Attempting to shutdown " - "process gracefully."); - workers_may_exit = 1; - } - - while (!workers_may_exit) { - apr_int16_t event; - srv = apr_poll(pollset, num_listensocks, &n, -1); - - if (srv != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(srv)) { - continue; - } - - /* apr_poll() will only return errors in catastrophic - * circumstances. Let's try exiting gracefully, for now. */ - ap_log_error(APLOG_MARK, APLOG_ERR, srv, (const server_rec *) - ap_server_conf, "apr_poll: (listen)"); - workers_may_exit = 1; - } - if (workers_may_exit) break; - - /* find a listener */ - lr = last_lr; - do { - lr = lr->next; - if (lr == NULL) { - lr = ap_listeners; - } - /* XXX: Should we check for POLLERR? */ - apr_poll_revents_get(&event, lr->sd, pollset); - if (event & (APR_POLLIN)) { - last_lr = lr; - goto got_fd; - } - } while (lr != last_lr); - } - got_fd: - if (!workers_may_exit) { - rv = lr->accept_func(&csd, lr, ptrans); - if (rv == APR_EGENERAL) { - /* E[NM]FILE, ENOMEM, etc */ - workers_may_exit = 1; - } - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(process_accept_mutex))) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to shutdown " - "process gracefully."); - workers_may_exit = 1; - } - apr_thread_mutex_unlock(thread_accept_mutex); - apr_thread_mutex_lock(idle_thread_count_mutex); - if (idle_thread_count > min_spare_threads) { - idle_thread_count--; - } - else { - if (!start_thread()) { - idle_thread_count--; - } - } - apr_thread_mutex_unlock(idle_thread_count_mutex); - if (setjmp(jmpbuffer) != 1) { - process_socket(ptrans, csd, conn_id, bucket_alloc); - } - else { - thread_socket_table[thread_num] = AP_PERCHILD_THISCHILD; - } - requests_this_child--; - } - else { - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(process_accept_mutex))) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to shutdown " - "process gracefully."); - workers_may_exit = 1; - } - apr_thread_mutex_unlock(thread_accept_mutex); - apr_thread_mutex_lock(idle_thread_count_mutex); - idle_thread_count--; - apr_thread_mutex_unlock(idle_thread_count_mutex); - break; - } - apr_pool_clear(ptrans); - } - - apr_thread_mutex_lock(thread_pool_parent_mutex); - ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD, - (request_rec *) NULL); - apr_pool_destroy(tpool); - apr_thread_mutex_unlock(thread_pool_parent_mutex); - apr_thread_mutex_lock(worker_thread_count_mutex); - worker_thread_count--; - worker_thread_free_ids[worker_thread_count] = thread_num; - if (worker_thread_count == 0) { - /* All the threads have exited, now finish the shutdown process - * by signalling the sigwait thread */ - kill(my_pid, SIGTERM); - } - apr_thread_mutex_unlock(worker_thread_count_mutex); - - apr_bucket_alloc_destroy(bucket_alloc); - - return NULL; -} - - - -/* Set group privileges. - * - * Note that we use the username as set in the config files, rather than - * the lookup of to uid --- the same uid may have multiple passwd entries, - * with different sets of groups for each. - */ - -static int set_group_privs(uid_t uid, gid_t gid) -{ - if (!geteuid()) { - const char *name; - - /* Get username if passed as a uid */ - - struct passwd *ent; - - if ((ent = getpwuid(uid)) == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, - "getpwuid: couldn't determine user name from uid %u, " - "you probably need to modify the User directive", - (unsigned)uid); - return -1; - } - - name = ent->pw_name; - - /* - * Set the GID before initgroups(), since on some platforms - * setgid() is known to zap the group list. - */ - if (setgid(gid) == -1) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, - "setgid: unable to set group id to Group %u", - (unsigned)gid); - return -1; - } - - /* Reset `groups' attributes. */ - - if (initgroups(name, gid) == -1) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, - "initgroups: unable to set groups for User %s " - "and Group %u", name, (unsigned)gid); - return -1; - } - } - return 0; -} - - -static int perchild_setup_child(int childnum) -{ - child_info_t *ug = &child_info_table[childnum]; - - if (ug->uid == -1 && ug->gid == -1) { - return unixd_setup_child(); - } - if (set_group_privs(ug->uid, ug->gid)) { - return -1; - } - /* Only try to switch if we're running as root */ - if (!geteuid() - && ( -#ifdef _OSD_POSIX - os_init_job_environment(server_conf, unixd_config.user_name, - one_process) != 0 || -#endif - setuid(ug->uid) == -1)) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, - "setuid: unable to change to uid: %ld", - (long) ug->uid); - return -1; - } - return 0; -} - -static int check_signal(int signum) -{ - switch (signum) { - case SIGTERM: - case SIGINT: - just_die(signum); - return 1; - } - return 0; -} - -typedef struct perchild_header { - char *headers; - apr_pool_t *p; -} perchild_header; - -/* Send a single HTTP header field to the client. Note that this function - * is used in calls to table_do(), so their interfaces are co-dependent. - * In other words, don't change this one without checking table_do in alloc.c. - * It returns true unless there was a write error of some kind. - */ -static int perchild_header_field(perchild_header *h, - const char *fieldname, const char *fieldval) -{ - apr_pstrcat(h->p, h->headers, fieldname, ": ", fieldval, CRLF, NULL); - return 1; -} - - -static void child_main(int child_num_arg) -{ - int i; - apr_status_t rv; - apr_socket_t *sock = NULL; - ap_listen_rec *lr; - - my_pid = getpid(); - ap_fatal_signal_child_setup(ap_server_conf); - child_num = child_num_arg; - apr_pool_create(&pchild, pconf); - - for (lr = ap_listeners ; lr->next != NULL; lr = lr->next) { - continue; - } - - apr_os_sock_put(&sock, &child_info_table[child_num].input, pconf); - lr->next = apr_palloc(pconf, sizeof(*lr)); - lr->next->sd = sock; - lr->next->active = 1; - lr->next->accept_func = receive_from_other_child; - lr->next->next = NULL; - lr = lr->next; - num_listensocks++; - - /*stuff to do before we switch id's, so we have permissions.*/ - - rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&process_accept_mutex, - ap_lock_fname, pchild)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize cross-process lock in child"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (perchild_setup_child(child_num)) { - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_run_child_init(pchild, ap_server_conf); - - /*done with init critical section */ - - apr_setup_signal_thread(); - - requests_this_child = ap_max_requests_per_child; - - - /* Setup worker threads */ - - if (threads_to_start > max_threads) { - threads_to_start = max_threads; - } - idle_thread_count = threads_to_start; - worker_thread_count = 0; - worker_thread_free_ids = (int *)apr_pcalloc(pchild, thread_limit * sizeof(int)); - for (i = 0; i < max_threads; i++) { - worker_thread_free_ids[i] = i; - } - apr_pool_create(&thread_pool_parent, pchild); - apr_thread_mutex_create(&thread_pool_parent_mutex, - APR_THREAD_MUTEX_DEFAULT, pchild); - apr_thread_mutex_create(&idle_thread_count_mutex, - APR_THREAD_MUTEX_DEFAULT, pchild); - apr_thread_mutex_create(&worker_thread_count_mutex, - APR_THREAD_MUTEX_DEFAULT, pchild); - apr_thread_mutex_create(&pipe_of_death_mutex, - APR_THREAD_MUTEX_DEFAULT, pchild); - apr_thread_mutex_create(&thread_accept_mutex, - APR_THREAD_MUTEX_DEFAULT, pchild); - - apr_threadattr_create(&worker_thread_attr, pchild); - apr_threadattr_detach_set(worker_thread_attr, 1); - - /* We are creating worker threads right now */ - for (i=0; i < threads_to_start; i++) { - /* start_thread shouldn't fail here */ - if (!start_thread()) { - break; - } - } - - apr_signal_thread(check_signal); -} - -static int make_child(server_rec *s, int slot) -{ - int pid; - - if (slot + 1 > ap_max_daemons_limit) { - ap_max_daemons_limit = slot + 1; - } - - if (one_process) { - set_signals(); - ap_child_table[slot].pid = getpid(); - ap_child_table[slot].status = SERVER_ALIVE; - child_main(slot); - } - (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, - (request_rec *) NULL); - - if ((pid = fork()) == -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, - "fork: Unable to fork new process"); - /* In case system resources are maxxed out, we don't want - * Apache running away with the CPU trying to fork over and - * over and over again. */ - sleep(10); - - return -1; - } - - if (!pid) { -#ifdef HAVE_BINDPROCESSOR - /* By default, AIX binds to a single processor. This bit unbinds - * children which will then bind to another CPU. - */ - int status = bindprocessor(BINDPROCESS, (int)getpid(), - PROCESSOR_CLASS_ANY); - if (status != OK) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, - ap_server_conf, "processor unbind failed %d", status); - } -#endif - - RAISE_SIGSTOP(MAKE_CHILD); - - /* XXX - For an unthreaded server, a signal handler will be necessary - * apr_signal(SIGTERM, just_die); - */ - child_main(slot); - clean_child_exit(0); - } - /* else */ - ap_child_table[slot].pid = pid; - ap_child_table[slot].status = SERVER_ALIVE; - - return 0; -} - -/* start up a bunch of children */ -static int startup_children(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < num_daemons; ++i) { - if (ap_child_table[i].pid) { - continue; - } - if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; - } - return number_to_start; -} - - -/* - * spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (32) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_child_maintenance(void) -{ - int i; - int free_length; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead = -1; - - /* initialize the free_list */ - free_length = 0; - - for (i = 0; i < num_daemons; ++i) { - if (ap_child_table[i].pid == 0) { - if (free_length < spawn_rate) { - free_slots[free_length] = i; - ++free_length; - } - } - else { - last_non_dead = i; - } - - if (i >= ap_max_daemons_limit && free_length >= spawn_rate) { - break; - } - } - ap_max_daemons_limit = last_non_dead + 1; - - if (free_length > 0) { - for (i = 0; i < free_length; ++i) { - make_child(ap_server_conf, free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } - else if (spawn_rate < MAX_SPAWN_RATE) { - spawn_rate *= 2; - } - } - else { - spawn_rate = 1; - } -} - -static void server_main_loop(int remaining_children_to_start) -{ - int child_slot; - apr_exit_why_e exitwhy; - int status; - apr_proc_t pid; - int i; - - while (!restart_pending && !shutdown_pending) { - ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); - - if (pid.pid != -1) { - if (ap_process_child_status(&pid, exitwhy, status) - == APEXIT_CHILDFATAL) { - shutdown_pending = 1; - child_fatal = 1; - return; - } - /* non-fatal death... note that it's gone in the child table and - * clean out the status table. */ - child_slot = -1; - for (i = 0; i < ap_max_daemons_limit; ++i) { - if (ap_child_table[i].pid == pid.pid) { - child_slot = i; - break; - } - } - if (child_slot >= 0) { - ap_child_table[child_slot].pid = 0; - ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); - - - if (remaining_children_to_start - && child_slot < num_daemons) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - make_child(ap_server_conf, child_slot); - --remaining_children_to_start; - } -#if APR_HAS_OTHER_CHILD - } - else if (apr_proc_other_child_read(&pid, status) == 0) { - /* handled */ -#endif - } - else if (is_graceful) { - /* Great, we've probably just lost a slot in the - * child table. Somehow we don't know about this - * child. - */ - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, - ap_server_conf, - "long lost child came home! (pid %ld)", - (long)pid.pid); - } - /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ - continue; - } - else if (remaining_children_to_start) { - /* we hit a 1 second timeout in which none of the previous - * generation of children needed to be reaped... so assume - * they're all done, and pick up the slack if any is left. - */ - remaining_children_to_start = \ - startup_children(remaining_children_to_start); - /* In any event we really shouldn't do the code below because - * few of the servers we just started are in the IDLE state - * yet, so we'd mistakenly create an extra server. - */ - continue; - } - - perform_child_maintenance(); - } -} - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - int remaining_children_to_start; - int i; - apr_status_t rv; - apr_size_t one = 1; - ap_listen_rec *lr; - apr_socket_t *sock = NULL; - int fd; - - ap_log_pid(pconf, ap_pid_fname); - - first_server_limit = server_limit; - first_thread_limit = thread_limit; - if (changed_limit_at_restart) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "WARNING: Attempt to change ServerLimit or ThreadLimit " - "ignored during restart"); - changed_limit_at_restart = 0; - } - - ap_server_conf = s; - - if ((ap_accept_lock_mech == APR_LOCK_SYSVSEM) || - (ap_accept_lock_mech == APR_LOCK_POSIXSEM)) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "Server configured for an accept lock mechanism that " - "cannot be used with perchild. Falling back to FCNTL."); - ap_accept_lock_mech = APR_LOCK_FCNTL; - } - - /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%u", - ap_server_root_relative(_pconf, ap_lock_fname), - my_pid); - rv = SAFE_ACCEPT(apr_proc_mutex_create(&process_accept_mutex, - ap_lock_fname, ap_accept_lock_mech, - _pconf)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create cross-process lock"); - return 1; - } - - if (!is_graceful) { - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - return 1; - } - } - /* Initialize the child table */ - if (!is_graceful) { - for (i = 0; i < server_limit; i++) { - ap_child_table[i].pid = 0; - } - } - - /* We need to put the new listeners at the end of the ap_listeners - * list. If we don't, then the pool will be cleared before the - * open_logs phase is called for the second time, and ap_listeners - * will have only invalid data. If that happens, then the sockets - * that we opened using make_sock() will be lost, and the server - * won't start. - */ - for (lr = ap_listeners ; lr->next != NULL; lr = lr->next) { - continue; - } - - apr_os_file_get(&fd, pipe_of_death_in); - apr_os_sock_put(&sock, &fd, pconf); - lr->next = apr_palloc(pconf, sizeof(*lr)); - lr->next->sd = sock; - lr->next->active = 1; - lr->next->accept_func = check_pipe_of_death; - lr->next->next = NULL; - lr = lr->next; - num_listensocks++; - - set_signals(); - - /* If we're doing a graceful_restart then we're going to see a lot - * of children exiting immediately when we get into the main loop - * below (because we just sent them AP_SIG_GRACEFUL). This happens - * pretty rapidly... and for each one that exits we'll start a new one - * until we reach at least daemons_min_free. But we may be permitted to - * start more than that, so we'll just keep track of how many we're - * supposed to start up without the 1 second penalty between each fork. - */ - remaining_children_to_start = num_daemons; - if (!is_graceful) { - remaining_children_to_start = \ - startup_children(remaining_children_to_start); - } - else { - /* give the system some time to recover before kicking into - * exponential mode */ - hold_off_on_exponential_spawning = 10; - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(process_accept_mutex), - apr_proc_mutex_defname()); -#endif - restart_pending = shutdown_pending = 0; - - server_main_loop(remaining_children_to_start); - - if (shutdown_pending) { - /* Time to gracefully shut down: - * Kill child processes, tell them to call child_exit, etc... - */ - if (unixd_killpg(getpgrp(), SIGTERM) < 0) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "killpg SIGTERM"); - } - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - - if (!child_fatal) { - /* cleanup pid file on normal shutdown */ - const char *pidfile = NULL; - pidfile = ap_server_root_relative (pconf, ap_pid_fname); - if (pidfile != NULL && unlink(pidfile) == 0) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "removed PID file %s (pid=%ld)", - pidfile, (long)getpid()); - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, - ap_server_conf, "caught SIGTERM, shutting down"); - } - return 1; - } - - /* we've been told to restart */ - apr_signal(SIGHUP, SIG_IGN); - - if (one_process) { - /* not worth thinking about */ - return 1; - } - - if (is_graceful) { - char char_of_death = '!'; - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, - ap_server_conf, AP_SIG_GRACEFUL_STRING " received. " - "Doing graceful restart"); - - /* This is mostly for debugging... so that we know what is still - * gracefully dealing with existing request. - */ - - for (i = 0; i < num_daemons; ++i) { - if (ap_child_table[i].pid) { - ap_child_table[i].status = SERVER_DYING; - } - } - /* give the children the signal to die */ - for (i = 0; i < num_daemons;) { - if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, - &one)) != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(rv)) continue; - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, - "write pipe_of_death"); - } - i++; - } - } - else { - /* Kill 'em all. Since the child acts the same on the parents SIGTERM - * and a SIGHUP, we may as well use the same signal, because some user - * pthreads are stealing signals from us left and right. - */ - if (unixd_killpg(getpgrp(), SIGTERM) < 0) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "killpg SIGTERM"); - } - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, - ap_server_conf, "SIGHUP received. Attempting to restart"); - } - return 0; -} - -/* This really should be a post_config hook, but the error log is already - * redirected by that point, so we need to do this in the open_logs phase. - */ -static int perchild_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - apr_status_t rv; - - pconf = p; - ap_server_conf = s; - - if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, - NULL, "no listening sockets available, shutting down"); - return DONE; - } - - ap_log_pid(pconf, ap_pid_fname); - - if ((rv = ap_mpm_pod_open(pconf, &pod))) { - ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, - "Could not open pipe-of-death."); - return DONE; - } - - if ((rv = apr_file_pipe_create(&pipe_of_death_in, &pipe_of_death_out, - pconf)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, - (const server_rec*) ap_server_conf, - "apr_file_pipe_create (pipe_of_death)"); - exit(1); - } - if ((rv = apr_file_pipe_timeout_set(pipe_of_death_in, 0)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, - (const server_rec*) ap_server_conf, - "apr_file_pipe_timeout_set (pipe_of_death)"); - exit(1); - } - - return OK; -} - -static int perchild_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) -{ - static int restart_num = 0; - int no_detach, debug, foreground; - ap_directive_t *pdir; - int i; - int tmp_server_limit = DEFAULT_SERVER_LIMIT; - int tmp_thread_limit = DEFAULT_THREAD_LIMIT; - apr_status_t rv; - - debug = ap_exists_config_define("DEBUG"); - - if (debug) { - foreground = one_process = 1; - no_detach = 0; - } - else { - one_process = ap_exists_config_define("ONE_PROCESS"); - no_detach = ap_exists_config_define("NO_DETACH"); - foreground = ap_exists_config_define("FOREGROUND"); - } - - /* sigh, want this only the second time around */ - if (restart_num++ == 1) { - is_graceful = 0; - - if (!one_process && !foreground) { - rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND - : APR_PROC_DETACH_DAEMONIZE); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "apr_proc_detach failed"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - - my_pid = getpid(); - } - - unixd_pre_config(ptemp); - ap_listen_pre_config(); - num_daemons = DEFAULT_NUM_DAEMON; - threads_to_start = DEFAULT_START_THREAD; - min_spare_threads = DEFAULT_MIN_SPARE_THREAD; - max_spare_threads = DEFAULT_MAX_SPARE_THREAD; - max_threads = thread_limit; - ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - curr_child_num = 0; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - /* we need to know ServerLimit and ThreadLimit before we start processing - * the tree because we need to already have allocated child_info_table - */ - for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { - if (!strcasecmp(pdir->directive, "ServerLimit")) { - if (atoi(pdir->args) > tmp_server_limit) { - tmp_server_limit = atoi(pdir->args); - if (tmp_server_limit > MAX_SERVER_LIMIT) { - tmp_server_limit = MAX_SERVER_LIMIT; - } - } - } - else if (!strcasecmp(pdir->directive, "ThreadLimit")) { - if (atoi(pdir->args) > tmp_thread_limit) { - tmp_thread_limit = atoi(pdir->args); - if (tmp_thread_limit > MAX_THREAD_LIMIT) { - tmp_thread_limit = MAX_THREAD_LIMIT; - } - } - } - } - - child_info_table = (child_info_t *)apr_pcalloc(p, tmp_server_limit * sizeof(child_info_t)); - for (i = 0; i < tmp_server_limit; i++) { - child_info_table[i].uid = -1; - child_info_table[i].gid = -1; - child_info_table[i].input = -1; - child_info_table[i].output = -1; - } - - return OK; -} - -static int pass_request(request_rec *r) -{ - int rv; - apr_socket_t *thesock = ap_get_module_config(r->connection->conn_config, &core_module); - struct msghdr msg; - struct cmsghdr *cmsg; - int sfd; - struct iovec iov[2]; - conn_rec *c = r->connection; - apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); - apr_bucket_brigade *sockbb; - char request_body[HUGE_STRING_LEN] = "\0"; - apr_size_t l = sizeof(request_body); - perchild_header h; - apr_bucket *sockbuck; - perchild_server_conf *sconf = (perchild_server_conf *) - ap_get_module_config(r->server->module_config, - &mpm_perchild_module); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "passing request to another child. Vhost: %s, child %d %d", - apr_table_get(r->headers_in, "Host"), child_num, sconf->output); - ap_get_brigade(r->connection->input_filters, bb, AP_MODE_EXHAUSTIVE, APR_NONBLOCK_READ, - 0); - - for (sockbuck = APR_BRIGADE_FIRST(bb); sockbuck != APR_BRIGADE_SENTINEL(bb); - sockbuck = APR_BUCKET_NEXT(sockbuck)) { - if (APR_BUCKET_IS_SOCKET(sockbuck)) { - break; - } - } - - if (!sockbuck) { - } - sockbb = apr_brigade_split(bb, sockbuck); - - if (apr_brigade_flatten(bb, request_body, &l) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Unable to flatten brigade, declining request"); - return DECLINED; - } - - apr_os_sock_get(&sfd, thesock); - - h.p = r->pool; - h.headers = apr_pstrcat(h.p, r->the_request, CRLF, "Host: ", r->hostname, - CRLF, NULL); - apr_table_do((int (*) (void *, const char *, const char *)) - perchild_header_field, (void *) &h, r->headers_in, NULL); - h.headers = apr_pstrcat(h.p, h.headers, CRLF, NULL); - - iov[0].iov_base = h.headers; - iov[0].iov_len = strlen(h.headers) + 1; - iov[1].iov_base = request_body; - iov[1].iov_len = l + 1; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = 2; - - cmsg = apr_palloc(r->pool, sizeof(*cmsg) + sizeof(sfd)); - cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sfd); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - memcpy(CMSG_DATA(cmsg), &sfd, sizeof(sfd)); - - msg.msg_control = cmsg; - msg.msg_controllen = cmsg->cmsg_len; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Writing message to %d, passing sd: %d", sconf->output, sfd); - - if ((rv = sendmsg(sconf->output, &msg, 0)) == -1) { - apr_pool_destroy(r->pool); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Writing message failed %d %d", rv, errno); - return -1; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Writing message succeeded %d", rv); - - apr_pool_destroy(r->pool); - return 1; -} - -static char *make_perchild_socket(const char *fullsockname, int sd[2]) -{ - socketpair(PF_UNIX, SOCK_STREAM, 0, sd); - return NULL; -} - -static int perchild_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - int i; - server_rec *sr; - perchild_server_conf *sconf; - int def_sd[2]; - - def_sd[0] = -1; - def_sd[1] = -1; - - for (sr = s; sr; sr = sr->next) { - sconf = (perchild_server_conf *)ap_get_module_config(sr->module_config, - &mpm_perchild_module); - - if (sconf->input == -1) { - sconf->fullsockname = apr_pstrcat(sr->process->pool, - sconf->sockname, ".DEFAULT", NULL); - if (def_sd[0] == -1) { - if (!make_perchild_socket(sconf->fullsockname, def_sd)) { - /* log error */ - } - } - sconf->input = def_sd[0]; - sconf->output = def_sd[1]; - } - } - - for (i = 0; i < num_daemons; i++) { - if (child_info_table[i].uid == -1) { - child_info_table[i].input = def_sd[0]; - child_info_table[i].output = def_sd[1]; - } - } - - thread_socket_table = (int *)apr_pcalloc(p, thread_limit * sizeof(int)); - for (i = 0; i < thread_limit; i++) { - thread_socket_table[i] = AP_PERCHILD_THISCHILD; - } - ap_child_table = (ap_ctable *)apr_pcalloc(p, server_limit * sizeof(ap_ctable)); - - return OK; -} - -static int perchild_post_read(request_rec *r) -{ - int thread_num = r->connection->id % thread_limit; - perchild_server_conf *sconf = (perchild_server_conf *) - ap_get_module_config(r->server->module_config, - &mpm_perchild_module); - - if (thread_socket_table[thread_num] != AP_PERCHILD_THISCHILD) { - apr_socket_t *csd = NULL; - - apr_os_sock_put(&csd, &thread_socket_table[thread_num], - r->connection->pool); - ap_sock_disable_nagle(csd); - ap_set_module_config(r->connection->conn_config, &core_module, csd); - return OK; - } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Determining if request should be passed. " - "Child Num: %d, SD: %d, sd from table: %d, hostname from server: %s", child_num, - sconf->input, child_info_table[child_num].input, - r->server->server_hostname); - /* sconf is the server config for this vhost, so if our socket - * is not the same that was set in the config, then the request - * needs to be passed to another child. */ - if (sconf->input != child_info_table[child_num].input) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Passing request."); - if (pass_request(r) == -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, - ap_server_conf, "Could not pass request to proper " - "child, request will not be honored."); - } - longjmp(jmpbuffer, 1); - } - return OK; - } - return OK; -} - -static void perchild_hooks(apr_pool_t *p) -{ - /* The perchild open_logs phase must run before the core's, or stderr - * will be redirected to a file, and the messages won't print to the - * console. - */ - static const char *const aszSucc[] = {"core.c", NULL}; - one_process = 0; - - ap_hook_open_logs(perchild_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); - ap_hook_pre_config(perchild_pre_config, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_post_config(perchild_post_config, NULL, NULL, APR_HOOK_MIDDLE); - - /* Both of these must be run absolutely first. If this request isn't for - * this server then we need to forward it to the proper child. No sense - * tying up this server running more post_read request hooks if it is - * just going to be forwarded along. The process_connection hook allows - * perchild to receive the passed request correctly, by automatically - * filling in the core_input_filter's ctx pointer. - */ - ap_hook_post_read_request(perchild_post_read, NULL, NULL, - APR_HOOK_REALLY_FIRST); - ap_hook_process_connection(perchild_process_connection, NULL, NULL, - APR_HOOK_REALLY_FIRST); -} - -static const char *set_num_daemons(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - num_daemons = atoi(arg); - if (num_daemons > server_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: NumServers of %d exceeds ServerLimit value " - "of %d servers,", num_daemons, server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering NumServers to %d. To increase, please " - "see the", server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " ServerLimit directive."); - num_daemons = server_limit; - } - else if (num_daemons < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require NumServers > 0, setting to 1"); - num_daemons = 1; - } - return NULL; -} - -static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - threads_to_start = atoi(arg); - if (threads_to_start > thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: StartThreads of %d exceeds ThreadLimit value" - " of %d threads,", threads_to_start, - thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering StartThreads to %d. To increase, please" - " see the", thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " ThreadLimit directive."); - } - else if (threads_to_start < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require StartThreads > 0, setting to 1"); - threads_to_start = 1; - } - return NULL; -} - -static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - min_spare_threads = atoi(arg); - if (min_spare_threads <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - min_spare_threads = 1; - } - - return NULL; -} - -static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - max_spare_threads = atoi(arg); - if (max_spare_threads >= thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set higher than"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "ThreadLimit. Resetting to %d", thread_limit); - max_spare_threads = thread_limit; - } - return NULL; -} - -static const char *set_max_threads(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - max_threads = atoi(arg); - if (max_threads > thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MaxThreadsPerChild set higher than"); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "ThreadLimit. Resetting to %d", thread_limit); - max_threads = thread_limit; - } - return NULL; -} - -static const char *set_child_per_uid(cmd_parms *cmd, void *dummy, const char *u, - const char *g, const char *num) -{ - int i; - int max_this_time = atoi(num) + curr_child_num; - - - for (i = curr_child_num; i < max_this_time; i++, curr_child_num++) { - if (i > num_daemons) { - return "Trying to use more child ID's than NumServers. Increase " - "NumServers in your config file."; - } - - child_info_table[i].uid = ap_uname2id(u); - child_info_table[i].gid = ap_gname2id(g); - -#ifndef BIG_SECURITY_HOLE - if (child_info_table[i].uid == 0 || child_info_table[i].gid == 0) { - return "Assigning root user/group to a child."; - } -#endif - } - return NULL; -} - -static const char *assign_childuid(cmd_parms *cmd, void *dummy, const char *uid, - const char *gid) -{ - int i; - int matching = 0; - int u = ap_uname2id(uid); - int g = ap_gname2id(gid); - const char *errstr; - int socks[2]; - perchild_server_conf *sconf = (perchild_server_conf *) - ap_get_module_config(cmd->server->module_config, - &mpm_perchild_module); - - sconf->fullsockname = apr_pstrcat(cmd->pool, sconf->sockname, ".", uid, - ":", gid, NULL); - - if ((errstr = make_perchild_socket(sconf->fullsockname, socks))) { - return errstr; - } - - sconf->input = socks[0]; - sconf->output = socks[1]; - - for (i = 0; i < num_daemons; i++) { - if (u == child_info_table[i].uid && g == child_info_table[i].gid) { - child_info_table[i].input = sconf->input; - child_info_table[i].output = sconf->output; - matching++; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, - "filling out child_info_table; UID: %d, GID: %d, " - "SD: %d %d, OUTPUT: %d %d, Child Num: %d", - child_info_table[i].uid, child_info_table[i].gid, - sconf->input, child_info_table[i].input, sconf->output, - child_info_table[i].output, i); - } - } - - if (!matching) { - return "Unable to find process with matching uid/gid."; - } - return NULL; -} - -static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_server_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_server_limit = atoi(arg); - /* you cannot change ServerLimit across a restart; ignore - * any such attempts - */ - if (first_server_limit && - tmp_server_limit != server_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - server_limit = tmp_server_limit; - - if (server_limit > MAX_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ServerLimit of %d exceeds compile time limit " - "of %d servers,", server_limit, MAX_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); - server_limit = MAX_SERVER_LIMIT; - } - else if (server_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ServerLimit > 0, setting to 1"); - server_limit = 1; - } - return NULL; -} - -static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_thread_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_thread_limit = atoi(arg); - /* you cannot change ThreadLimit across a restart; ignore - * any such attempts - */ - if (first_thread_limit && - tmp_thread_limit != thread_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - thread_limit = tmp_thread_limit; - - if (thread_limit > MAX_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadLimit of %d exceeds compile time limit " - "of %d servers,", thread_limit, MAX_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); - thread_limit = MAX_THREAD_LIMIT; - } - else if (thread_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadLimit > 0, setting to 1"); - thread_limit = 1; - } - return NULL; -} - -static const command_rec perchild_cmds[] = { -UNIX_DAEMON_COMMANDS, -LISTEN_COMMANDS, -AP_INIT_TAKE1("NumServers", set_num_daemons, NULL, RSRC_CONF, - "Number of children alive at the same time"), -AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF, - "Number of threads each child creates"), -AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, - "Minimum number of idle threads per child, to handle " - "request spikes"), -AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, - "Maximum number of idle threads per child"), -AP_INIT_TAKE1("MaxThreadsPerChild", set_max_threads, NULL, RSRC_CONF, - "Maximum number of threads per child"), -AP_INIT_TAKE3("ChildperUserID", set_child_per_uid, NULL, RSRC_CONF, - "Specify a User and Group for a specific child process."), -AP_INIT_TAKE2("AssignUserID", assign_childuid, NULL, RSRC_CONF, - "Tie a virtual host to a specific child process."), -AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, - "Maximum value of NumServers for this run of Apache"), -AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, - "Maximum worker threads in a server for this run of Apache"), -{ NULL } -}; - -static void *perchild_create_config(apr_pool_t *p, server_rec *s) -{ - perchild_server_conf *c = (perchild_server_conf *) - apr_pcalloc(p, sizeof(perchild_server_conf)); - - c->input = -1; - c->output = -1; - return c; -} - -module AP_MODULE_DECLARE_DATA mpm_perchild_module = { - MPM20_MODULE_STUFF, - ap_mpm_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - perchild_create_config, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - perchild_cmds, /* command apr_table_t */ - perchild_hooks /* register_hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/Makefile.in deleted file mode 100644 index ea0acb69..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libthreadpool.la -LTLIBRARY_SOURCES = threadpool.c pod.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/README b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/README deleted file mode 100644 index 86e8524c..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/README +++ /dev/null @@ -1,12 +0,0 @@ -Threadpool MPM: -This is an experimental variant of the standard worker MPM. -Rather than queuing connections like the worker MPM, the threadpool -MPM queues idle worker threads and hands each accepted connection -to the next available worker. - -The threadpool MPM can't match the performance of the worker MPM -in benchmark testing. As of 2.0.39, some of the key load-throtting -concepts from the threadpool MPM have been incorporated into the -worker MPM. The threadpool code is useful primarily as a research -platform; for general-purpose use, and for any production environments, -use worker instead. diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/config5.m4 b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/config5.m4 deleted file mode 100644 index 667b534a..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/config5.m4 +++ /dev/null @@ -1,6 +0,0 @@ -dnl ## XXX - Need a more thorough check of the proper flags to use - -if test "$MPM_NAME" = "threadpool" ; then - AC_CHECK_FUNCS(pthread_kill) - APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/mpm.h deleted file mode 100644 index 222040bd..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/mpm.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "scoreboard.h" -#include "unixd.h" - -#ifndef APACHE_MPM_THREADPOOL_H -#define APACHE_MPM_THREADPOOL_H - -#define THREADPOOL_MPM - -#define MPM_NAME "ThreadPool" - -#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -#define AP_MPM_WANT_WAIT_OR_TIMEOUT -#define AP_MPM_WANT_PROCESS_CHILD_STATUS -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_LOCKFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -#define AP_MPM_WANT_SIGNAL_SERVER -#define AP_MPM_WANT_SET_MAX_MEM_FREE -#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER -#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK - -#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) -#define MPM_ACCEPT_FUNC unixd_accept - -extern int ap_threads_per_child; -extern int ap_max_daemons_limit; -extern server_rec *ap_server_conf; -extern char ap_coredump_dir[MAX_STRING_LEN]; - -#endif /* APACHE_MPM_THREADPOOL_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/mpm_default.h deleted file mode 100644 index d5a33989..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/mpm_default.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of servers to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_DAEMON -#define DEFAULT_START_DAEMON 3 -#endif - -/* Maximum number of *free* server processes --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_FREE_DAEMON -#define DEFAULT_MAX_FREE_DAEMON 10 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_FREE_DAEMON -#define DEFAULT_MIN_FREE_DAEMON 3 -#endif - -#ifndef DEFAULT_THREADS_PER_CHILD -#define DEFAULT_THREADS_PER_CHILD 25 -#endif - -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/pod.c b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/pod.c deleted file mode 100644 index 2f26130c..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/pod.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "pod.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - -AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod) -{ - apr_status_t rv; - - *pod = apr_palloc(p, sizeof(**pod)); - rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); - if (rv != APR_SUCCESS) { - return rv; - } -/* - apr_file_pipe_timeout_set((*pod)->pod_in, 0); -*/ - (*pod)->p = p; - - return APR_SUCCESS; -} - -AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod) -{ - char c; - apr_os_file_t fd; - int rc; - - /* we need to surface EINTR so we'll have to grab the - * native file descriptor and do the OS read() ourselves - */ - apr_os_file_get(&fd, pod->pod_in); - rc = read(fd, &c, 1); - if (rc == 1) { - switch(c) { - case RESTART_CHAR: - return AP_RESTART; - case GRACEFUL_CHAR: - return AP_GRACEFUL; - } - } - return AP_NORESTART; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod) -{ - apr_status_t rv; - - rv = apr_file_close(pod->pod_out); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_file_close(pod->pod_in); - if (rv != APR_SUCCESS) { - return rv; - } - return rv; -} - -static apr_status_t pod_signal_internal(ap_pod_t *pod, int graceful) -{ - apr_status_t rv; - char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; - apr_size_t one = 1; - - do { - rv = apr_file_write(pod->pod_out, &char_of_death, &one); - } while (APR_STATUS_IS_EINTR(rv)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, - "write pipe_of_death"); - } - return rv; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful) -{ - return pod_signal_internal(pod, graceful); -} - -AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful) -{ - int i; - apr_status_t rv = APR_SUCCESS; - - for (i = 0; i < num && rv == APR_SUCCESS; i++) { - rv = pod_signal_internal(pod, graceful); - } -} - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/pod.h b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/pod.h deleted file mode 100644 index 21651e6f..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/pod.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_strings.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "http_main.h" -#include "mpm.h" -#include "mpm_common.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "mpm_default.h" - -#define RESTART_CHAR '$' -#define GRACEFUL_CHAR '!' - -#define AP_RESTART 0 -#define AP_GRACEFUL 1 - -typedef struct ap_pod_t ap_pod_t; - -struct ap_pod_t { - apr_file_t *pod_in; - apr_file_t *pod_out; - apr_pool_t *p; -}; - -AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod); -AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod); -AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod); -AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful); -AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful); diff --git a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/threadpool.c b/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/threadpool.c deleted file mode 100644 index 50de500e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/experimental/threadpool/threadpool.c +++ /dev/null @@ -1,2229 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The purpose of this MPM is to fix the design flaws in the threaded - * model. Because of the way that pthreads and mutex locks interact, - * it is basically impossible to cleanly gracefully shutdown a child - * process if multiple threads are all blocked in accept. This model - * fixes those problems. - */ - -#include "apr.h" -#include "apr_portable.h" -#include "apr_strings.h" -#include "apr_file_io.h" -#include "apr_thread_proc.h" -#include "apr_signal.h" -#include "apr_poll.h" -#include "apr_thread_mutex.h" -#include "apr_thread_cond.h" -#include "apr_proc_mutex.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#if APR_HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif -#ifdef HAVE_SYS_PROCESSOR_H -#include <sys/processor.h> /* for bindprocessor() */ -#endif - -#if !APR_HAS_THREADS -#error The Worker MPM requires APR threads, but they are unavailable. -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "ap_mpm.h" -#include "pod.h" -#include "mpm_common.h" -#include "ap_listen.h" -#include "scoreboard.h" -#include "mpm_default.h" - -#include <signal.h> -#include <limits.h> /* for INT_MAX */ - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_SERVER_LIMIT -#define DEFAULT_SERVER_LIMIT 16 -#endif - -/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_SERVER_LIMIT -#define MAX_SERVER_LIMIT 20000 -#endif - -/* Limit on the threads per process. Clients will be locked out if more than - * this * server_limit are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_THREAD_LIMIT -#define DEFAULT_THREAD_LIMIT 64 -#endif - -/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_THREAD_LIMIT -#define MAX_THREAD_LIMIT 20000 -#endif - -/* - * Actual definitions of config globals - */ - -int ap_threads_per_child = 0; /* Worker threads per child */ -static int ap_daemons_to_start = 0; -static int min_spare_threads = 0; -static int max_spare_threads = 0; -static int ap_daemons_limit = 0; -static int server_limit = DEFAULT_SERVER_LIMIT; -static int first_server_limit; -static int thread_limit = DEFAULT_THREAD_LIMIT; -static int first_thread_limit; -static int changed_limit_at_restart; -static int dying = 0; -static int workers_may_exit = 0; -static int start_thread_may_exit = 0; -static int listener_may_exit = 0; -static int requests_this_child; -static int num_listensocks = 0; -static int resource_shortage = 0; -static int mpm_state = AP_MPMQ_STARTING; - -/* The structure used to pass unique initialization info to each thread */ -typedef struct { - int pid; - int tid; - int sd; -} proc_info; - -/* Structure used to pass information to the thread responsible for - * creating the rest of the threads. - */ -typedef struct { - apr_thread_t **threads; - apr_thread_t *listener; - int child_num_arg; - apr_threadattr_t *threadattr; -} thread_starter; - -#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We - * use this value to optimize routines that have to scan the entire - * scoreboard. - */ -int ap_max_daemons_limit = -1; - -static ap_pod_t *pod; - -/* *Non*-shared http_main globals... */ - -server_rec *ap_server_conf; - -/* The worker MPM respects a couple of runtime flags that can aid - * in debugging. Setting the -DNO_DETACH flag will prevent the root process - * from detaching from its controlling terminal. Additionally, setting - * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the - * child_main loop running in the process which originally started up. - * This gives you a pretty nice debugging environment. (You'll get a SIGHUP - * early in standalone_main; just continue through. This is the server - * trying to kill off any child processes which it might have lying - * around --- Apache doesn't keep track of their pids, it just sends - * SIGHUP to the process group, ignoring it in the root process. - * Continue through and you'll be fine.). - */ - -static int one_process = 0; - -#ifdef DEBUG_SIGSTOP -int raise_sigstop_flags; -#endif - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pchild; /* Pool for httpd child stuff */ - -static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main - thread. Use this instead */ -static pid_t parent_pid; -static apr_os_thread_t *listener_os_thread; - -/* Locks for accept serialization */ -static apr_proc_mutex_t *accept_mutex; - -#if APR_O_NONBLOCK_INHERITED -#undef SINGLE_LISTEN_UNSERIALIZED_ACCEPT -#endif /* APR_O_NONBLOCK_INHERITED */ - -#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT -#define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS) -#else -#define SAFE_ACCEPT(stmt) (stmt) -#endif - -/* The LISTENER_SIGNAL signal will be sent from the main thread to the - * listener thread to wake it up for graceful termination (what a child - * process from an old generation does when the admin does "apachectl - * graceful"). This signal will be blocked in all threads of a child - * process except for the listener thread. - */ -#define LISTENER_SIGNAL SIGHUP - - -/* Possible states of a worker thread. */ -typedef enum { - WORKER_IDLE, - WORKER_BUSY, - WORKER_TERMINATED -} worker_state_e; - -/* Structure used to wake up an idle worker thread - */ -typedef struct { - apr_pool_t *pool; - apr_socket_t *csd; - worker_state_e state; - apr_thread_cond_t *cond; - apr_thread_mutex_t *mutex; -} worker_wakeup_info; - -/* Structure used to hold a stack of idle worker threads - */ -typedef struct { - apr_thread_mutex_t *mutex; - apr_thread_cond_t *cond; - worker_wakeup_info **stack; - apr_size_t nelts; - apr_size_t nalloc; - int terminated; -} worker_stack; - -static worker_stack* worker_stack_create(apr_pool_t *pool, apr_size_t max) -{ - apr_status_t rv; - worker_stack *stack = (worker_stack *)apr_palloc(pool, sizeof(*stack)); - - if ((rv = apr_thread_mutex_create(&stack->mutex, APR_THREAD_MUTEX_DEFAULT, - pool)) != APR_SUCCESS) { - return NULL; - } - if ((rv = apr_thread_cond_create(&stack->cond, pool)) != APR_SUCCESS) { - return NULL; - } - stack->nelts = 0; - stack->nalloc = max; - stack->stack = - (worker_wakeup_info **)apr_palloc(pool, stack->nalloc * - sizeof(worker_wakeup_info *)); - stack->terminated = 0; - return stack; -} - -static apr_status_t worker_stack_wait(worker_stack *stack, - worker_wakeup_info *wakeup) -{ - apr_status_t rv; - - wakeup->state = WORKER_IDLE; - - if ((rv = apr_thread_mutex_lock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - if (stack->terminated) { - if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - return APR_EOF; - } - if (stack->nelts == stack->nalloc) { - if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - return APR_ENOSPC; - } - stack->stack[stack->nelts] = wakeup; - /* Signal a blocking listener thread only if we just made the - * stack non-empty. */ - if (stack->nelts++ == 0) { - (void)apr_thread_cond_signal(stack->cond); - } - if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - - /* At this point we've already added this worker to the stack, now - * we just wait until the listener has accept()ed a connection - * for us. */ - if ((rv = apr_thread_mutex_lock(wakeup->mutex)) != APR_SUCCESS) { - return rv; - } - while (wakeup->state == WORKER_IDLE) { - if ((rv = apr_thread_cond_wait(wakeup->cond, wakeup->mutex)) != - APR_SUCCESS) { - return rv; - } - } - if ((rv = apr_thread_mutex_unlock(wakeup->mutex)) != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -} - -static apr_status_t worker_stack_pop(worker_stack *stack, - worker_wakeup_info **worker) -{ - apr_status_t rv; - if ((rv = apr_thread_mutex_lock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - AP_DEBUG_ASSERT(stack->nelts >= 0); - while ((stack->nelts == 0) && (!stack->terminated)) { - rv = apr_thread_cond_wait(stack->cond, stack->mutex); - if (rv != APR_SUCCESS) { - apr_status_t rv2; - rv2 = apr_thread_mutex_unlock(stack->mutex); - if (rv2 != APR_SUCCESS) { - return rv2; - } - return rv; - } - } - if (stack->terminated) { - if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - return APR_EOF; - } - *worker = stack->stack[--stack->nelts]; - if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -} - -static apr_status_t worker_stack_terminate(worker_stack *stack) -{ - apr_status_t rv; - worker_wakeup_info *worker; - - if ((rv = apr_thread_mutex_lock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - stack->terminated = 1; - /* Wake up the listener thread. Although there will never be - * more than one thread blocking on this condition, broadcast - * just in case. */ - apr_thread_cond_broadcast(stack->cond); - while (stack->nelts) { - worker = stack->stack[--stack->nelts]; - apr_thread_mutex_lock(worker->mutex); - worker->csd = 0; - worker->state = WORKER_TERMINATED; - apr_thread_cond_signal(worker->cond); - apr_thread_mutex_unlock(worker->mutex); - } - if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -} - -static worker_stack *idle_worker_stack; - -static void wakeup_listener(void) -{ - apr_status_t rv; - - listener_may_exit = 1; - if (!idle_worker_stack) { - return; - } - if ((rv = apr_thread_mutex_lock(idle_worker_stack->mutex)) != APR_SUCCESS) { - return; - } - if ((rv = apr_thread_cond_signal(idle_worker_stack->cond)) != - APR_SUCCESS) { - return; - } - if ((rv = apr_thread_mutex_unlock(idle_worker_stack->mutex)) != APR_SUCCESS) { - return; - } - if (!listener_os_thread) { - /* XXX there is an obscure path that this doesn't handle perfectly: - * right after listener thread is created but before - * listener_os_thread is set, the first worker thread hits an - * error and starts graceful termination - */ - return; - } - /* - * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all - * platforms and wake up the listener thread since it is the only thread - * with SIGHUP unblocked, but that doesn't work on Linux - */ -#ifdef HAVE_PTHREAD_KILL - pthread_kill(*listener_os_thread, LISTENER_SIGNAL); -#else - kill(ap_my_pid, LISTENER_SIGNAL); -#endif -} - -#define ST_INIT 0 -#define ST_GRACEFUL 1 -#define ST_UNGRACEFUL 2 - -static int terminate_mode = ST_INIT; - -static void signal_threads(int mode) -{ - if (terminate_mode == mode) { - return; - } - terminate_mode = mode; - mpm_state = AP_MPMQ_STOPPING; - - /* in case we weren't called from the listener thread, wake up the - * listener thread - */ - wakeup_listener(); - - /* for ungraceful termination, let the workers exit now; - * for graceful termination, the listener thread will notify the - * workers to exit once it has stopped accepting new connections - */ - if (mode == ST_UNGRACEFUL) { - workers_may_exit = 1; - worker_stack_terminate(idle_worker_stack); - } -} - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_max_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_STATIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = server_limit; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = thread_limit; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = ap_threads_per_child; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = min_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = max_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = ap_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -/* a clean exit from a child with proper cleanup */ -static void clean_child_exit(int code) __attribute__ ((noreturn)); -static void clean_child_exit(int code) -{ - mpm_state = AP_MPMQ_STOPPING; - if (pchild) { - apr_pool_destroy(pchild); - } - exit(code); -} - -static void just_die(int sig) -{ - clean_child_exit(0); -} - -/***************************************************************** - * Connection structures and accounting... - */ - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; -static volatile int child_fatal; -ap_generation_t volatile ap_my_generation; - -/* - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at - * functions to initiate shutdown or restart without relying on signals. - * Previously this was initiated in sig_term() and restart() signal handlers, - * but we want to be able to start a shutdown/restart from other sources -- - * e.g. on Win32, from the service manager. Now the service manager can - * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that - * these functions can also be called by the child processes, since global - * variables are no longer used to pass on the required action to the parent. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. - */ - -static void ap_start_shutdown(void) -{ - mpm_state = AP_MPMQ_STOPPING; - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; -} - -/* do a graceful restart if graceful == 1 */ -static void ap_start_restart(int graceful) -{ - mpm_state = AP_MPMQ_STOPPING; - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = graceful; -} - -static void sig_term(int sig) -{ - ap_start_shutdown(); -} - -static void restart(int sig) -{ - ap_start_restart(sig == AP_SIG_GRACEFUL); -} - -static void set_signals(void) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; -#endif - - if (!one_process) { - ap_fatal_signal_setup(ap_server_conf, pconf); - } - -#ifndef NO_USE_SIGACTION - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGTERM)"); -#ifdef SIGINT - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGINT)"); -#endif -#ifdef SIGXCPU - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXCPU, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXCPU)"); -#endif -#ifdef SIGXFSZ - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXFSZ, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXFSZ)"); -#endif -#ifdef SIGPIPE - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGPIPE)"); -#endif - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -#else - if (!one_process) { -#ifdef SIGXCPU - apr_signal(SIGXCPU, SIG_DFL); -#endif /* SIGXCPU */ -#ifdef SIGXFSZ - apr_signal(SIGXFSZ, SIG_DFL); -#endif /* SIGXFSZ */ - } - - apr_signal(SIGTERM, sig_term); -#ifdef SIGHUP - apr_signal(SIGHUP, restart); -#endif /* SIGHUP */ -#ifdef AP_SIG_GRACEFUL - apr_signal(AP_SIG_GRACEFUL, restart); -#endif /* AP_SIG_GRACEFUL */ -#ifdef SIGPIPE - apr_signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - -#endif -} - -/***************************************************************** - * Here follows a long bunch of generic server bookkeeping stuff... - */ - -int ap_graceful_stop_signalled(void) - /* XXX this is really a bad confusing obsolete name - * maybe it should be ap_mpm_process_exiting? - */ -{ - /* note: for a graceful termination, listener_may_exit will be set before - * workers_may_exit, so check listener_may_exit - */ - return listener_may_exit; -} - -/***************************************************************** - * Child process main loop. - */ - -static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, - int my_thread_num, apr_bucket_alloc_t *bucket_alloc) -{ - conn_rec *current_conn; - long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); - int csd; - ap_sb_handle_t *sbh; - - ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); - apr_os_sock_get(&csd, sock); - - current_conn = ap_run_create_connection(p, ap_server_conf, sock, - conn_id, sbh, bucket_alloc); - if (current_conn) { - ap_process_connection(current_conn, sock); - ap_lingering_close(current_conn); - } -} - -/* requests_this_child has gone to zero or below. See if the admin coded - "MaxRequestsPerChild 0", and keep going in that case. Doing it this way - simplifies the hot path in worker_thread */ -static void check_infinite_requests(void) -{ - if (ap_max_requests_per_child) { - signal_threads(ST_GRACEFUL); - } - else { - /* wow! if you're executing this code, you may have set a record. - * either this child process has served over 2 billion requests, or - * you're running a threaded 2.0 on a 16 bit machine. - * - * I'll buy pizza and beers at Apachecon for the first person to do - * the former without cheating (dorking with INT_MAX, or running with - * uncommitted performance patches, for example). - * - * for the latter case, you probably deserve a beer too. Greg Ames - */ - - requests_this_child = INT_MAX; /* keep going */ - } -} - -static void unblock_signal(int sig) -{ - sigset_t sig_mask; - - sigemptyset(&sig_mask); - sigaddset(&sig_mask, sig); -#if defined(SIGPROCMASK_SETS_THREAD_MASK) - sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); -#else - pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); -#endif -} - -static void dummy_signal_handler(int sig) -{ - /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall, - * then we don't need this goofy function. - */ -} - -static void *listener_thread(apr_thread_t *thd, void * dummy) -{ - proc_info * ti = dummy; - int process_slot = ti->pid; - apr_pool_t *tpool = apr_thread_pool_get(thd); - void *csd = NULL; - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - int n; - apr_pollfd_t *pollset; - apr_status_t rv; - ap_listen_rec *lr, *last_lr = ap_listeners; - worker_wakeup_info *worker = NULL; - - free(ti); - - apr_poll_setup(&pollset, num_listensocks, tpool); - for(lr = ap_listeners ; lr != NULL ; lr = lr->next) - apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); - - /* Unblock the signal used to wake this thread up, and set a handler for - * it. - */ - unblock_signal(LISTENER_SIGNAL); - apr_signal(LISTENER_SIGNAL, dummy_signal_handler); - - /* TODO: Switch to a system where threads reuse the results from earlier - poll calls - manoj */ - while (1) { - /* TODO: requests_this_child should be synchronized - aaron */ - if (requests_this_child <= 0) { - check_infinite_requests(); - } - if (listener_may_exit) break; - - if (worker == NULL) { - rv = worker_stack_pop(idle_worker_stack, &worker); - if (APR_STATUS_IS_EOF(rv)) { - break; - } - else if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "worker_stack_pop failed"); - break; - } - ptrans = worker->pool; - } - AP_DEBUG_ASSERT(worker->state == WORKER_IDLE); - - if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (listener_may_exit) { - break; - } - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_lock failed. Attempting to shutdown " - "process gracefully."); - signal_threads(ST_GRACEFUL); - break; /* skip the lock release */ - } - - if (!APR_O_NONBLOCK_INHERITED && !ap_listeners->next) { - /* Only one listener, so skip the poll */ - lr = ap_listeners; - } - else { - while (!listener_may_exit) { - apr_status_t ret; - apr_int16_t event; - - ret = apr_poll(pollset, num_listensocks, &n, -1); - if (ret != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(ret)) { - continue; - } - - /* apr_poll() will only return errors in catastrophic - * circumstances. Let's try exiting gracefully, for now. */ - ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) - ap_server_conf, "apr_poll: (listen)"); - signal_threads(ST_GRACEFUL); - } - - if (listener_may_exit) break; - - /* find a listener */ - lr = last_lr; - do { - lr = lr->next; - if (lr == NULL) { - lr = ap_listeners; - } - /* XXX: Should we check for POLLERR? */ - apr_poll_revents_get(&event, lr->sd, pollset); - if (event & APR_POLLIN) { - last_lr = lr; - goto got_fd; - } - } while (lr != last_lr); - } - } - got_fd: - if (!listener_may_exit) { - rv = lr->accept_func(&csd, lr, ptrans); - /* later we trash rv and rely on csd to indicate success/failure */ - AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd); - - if (rv == APR_EGENERAL) { - /* E[NM]FILE, ENOMEM, etc */ - resource_shortage = 1; - signal_threads(ST_GRACEFUL); - } - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (listener_may_exit) { - break; - } - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - } - if (csd != NULL) { - /* Wake up the sleeping worker. */ - apr_thread_mutex_lock(worker->mutex); - worker->csd = (apr_socket_t *)csd; - worker->state = WORKER_BUSY; - /* Posix allows us to signal this condition without - * owning the associated mutex, but in that case it can - * not guarantee predictable scheduling. See - * _UNIX Network Programming: Interprocess Communication_ - * by W. Richard Stevens, Vol 2, 2nd Ed, pp. 170-171. */ - apr_thread_cond_signal(worker->cond); - apr_thread_mutex_unlock(worker->mutex); - worker = NULL; - } - } - else { - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - } - break; - } - } - - workers_may_exit = 1; - if (worker) { - apr_thread_mutex_lock(worker->mutex); - worker->state = WORKER_TERMINATED; - /* Posix allows us to signal this condition without - * owning the associated mutex, but in that case it can - * not guarantee predictable scheduling. See - * _UNIX Network Programming: Interprocess Communication_ - * by W. Richard Stevens, Vol 2, 2nd Ed, pp. 170-171. */ - apr_thread_cond_signal(worker->cond); - apr_thread_mutex_unlock(worker->mutex); - } - worker_stack_terminate(idle_worker_stack); - dying = 1; - ap_scoreboard_image->parent[process_slot].quiescing = 1; - - /* wake up the main thread */ - kill(ap_my_pid, SIGTERM); - - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -/* XXX For ungraceful termination/restart, we definitely don't want to - * wait for active connections to finish but we may want to wait - * for idle workers to get out of the queue code and release mutexes, - * since those mutexes are cleaned up pretty soon and some systems - * may not react favorably (i.e., segfault) if operations are attempted - * on cleaned-up mutexes. - */ -static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy) -{ - proc_info * ti = dummy; - int process_slot = ti->pid; - int thread_slot = ti->tid; - apr_bucket_alloc_t *bucket_alloc; - apr_pool_t *tpool = apr_thread_pool_get(thd); - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - apr_allocator_t *allocator; - apr_status_t rv; - worker_wakeup_info *wakeup; - - free(ti); - - ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); - - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - /* XXX: why is ptrans's parent not tpool? --jcw 08/2003 */ - apr_pool_create_ex(&ptrans, NULL, NULL, allocator); - apr_allocator_owner_set(allocator, ptrans); - bucket_alloc = apr_bucket_alloc_create_ex(allocator); - - wakeup = (worker_wakeup_info *)apr_palloc(tpool, sizeof(*wakeup)); - wakeup->pool = ptrans; - if ((rv = apr_thread_cond_create(&wakeup->cond, tpool)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_thread_cond_create failed. Attempting to shutdown " - "process gracefully."); - signal_threads(ST_GRACEFUL); - apr_thread_exit(thd, rv); - } - if ((rv = apr_thread_mutex_create(&wakeup->mutex, APR_THREAD_MUTEX_DEFAULT, - tpool)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_thread_mutex_create failed. Attempting to shutdown " - "process gracefully."); - signal_threads(ST_GRACEFUL); - apr_thread_exit(thd, rv); - } - - while (!workers_may_exit) { - ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); - rv = worker_stack_wait(idle_worker_stack, wakeup); - if (APR_STATUS_IS_EOF(rv)) { - break; /* The queue has been terminated. */ - } - else if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "worker_stack_wait failed"); - break; /* Treat all other errors as fatal. */ - } - else if (wakeup->state == WORKER_TERMINATED) { - break; /* They told us to quit. */ - } - AP_DEBUG_ASSERT(wakeup->state != WORKER_IDLE); - process_socket(ptrans, wakeup->csd, - process_slot, thread_slot, bucket_alloc); - requests_this_child--; /* FIXME: should be synchronized - aaron */ - apr_pool_clear(ptrans); - } - - ap_update_child_status_from_indexes(process_slot, thread_slot, - (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); - - apr_bucket_alloc_destroy(bucket_alloc); - - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -static int check_signal(int signum) -{ - switch (signum) { - case SIGTERM: - case SIGINT: - return 1; - } - return 0; -} - -static void create_listener_thread(thread_starter *ts) -{ - int my_child_num = ts->child_num_arg; - apr_threadattr_t *thread_attr = ts->threadattr; - proc_info *my_info; - apr_status_t rv; - - my_info = (proc_info *)malloc(sizeof(proc_info)); - my_info->pid = my_child_num; - my_info->tid = -1; /* listener thread doesn't have a thread slot */ - my_info->sd = 0; - rv = apr_thread_create(&ts->listener, thread_attr, listener_thread, - my_info, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create listener thread"); - /* In case system resources are maxxed out, we don't want - * Apache running away with the CPU trying to fork over and - * over and over again if we exit. - * XXX Jeff doesn't see how Apache is going to try to fork again since - * the exit code is APEXIT_CHILDFATAL - */ - apr_sleep(10 * APR_USEC_PER_SEC); - clean_child_exit(APEXIT_CHILDFATAL); - } - apr_os_thread_get(&listener_os_thread, ts->listener); -} - -/* XXX under some circumstances not understood, children can get stuck - * in start_threads forever trying to take over slots which will - * never be cleaned up; for now there is an APLOG_DEBUG message issued - * every so often when this condition occurs - */ -static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) -{ - thread_starter *ts = dummy; - apr_thread_t **threads = ts->threads; - apr_threadattr_t *thread_attr = ts->threadattr; - int child_num_arg = ts->child_num_arg; - int my_child_num = child_num_arg; - proc_info *my_info; - apr_status_t rv; - int i; - int threads_created = 0; - int loops; - int prev_threads_created; - - idle_worker_stack = worker_stack_create(pchild, ap_threads_per_child); - if (idle_worker_stack == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, - "worker_stack_create() failed"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - loops = prev_threads_created = 0; - while (1) { - /* ap_threads_per_child does not include the listener thread */ - for (i = 0; i < ap_threads_per_child; i++) { - int status = ap_scoreboard_image->servers[child_num_arg][i].status; - - if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { - continue; - } - - my_info = (proc_info *)malloc(sizeof(proc_info)); - if (my_info == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - my_info->pid = my_child_num; - my_info->tid = i; - my_info->sd = 0; - - /* We are creating threads right now */ - ap_update_child_status_from_indexes(my_child_num, i, - SERVER_STARTING, NULL); - /* We let each thread update its own scoreboard entry. This is - * done because it lets us deal with tid better. - */ - rv = apr_thread_create(&threads[i], thread_attr, - worker_thread, my_info, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again if we exit. */ - apr_sleep(10 * APR_USEC_PER_SEC); - clean_child_exit(APEXIT_CHILDFATAL); - } - threads_created++; - if (threads_created == 1) { - /* now that we have a worker thread, it makes sense to create - * a listener thread (we don't want a listener without a worker!) - */ - create_listener_thread(ts); - } - } - if (start_thread_may_exit || threads_created == ap_threads_per_child) { - break; - } - /* wait for previous generation to clean up an entry */ - apr_sleep(1 * APR_USEC_PER_SEC); - ++loops; - if (loops % 120 == 0) { /* every couple of minutes */ - if (prev_threads_created == threads_created) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "child %" APR_PID_T_FMT " isn't taking over " - "slots very quickly (%d of %d)", - ap_my_pid, threads_created, ap_threads_per_child); - } - prev_threads_created = threads_created; - } - } - - /* What state should this child_main process be listed as in the - * scoreboard...? - * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, - * (request_rec *) NULL); - * - * This state should be listed separately in the scoreboard, in some kind - * of process_status, not mixed in with the worker threads' status. - * "life_status" is almost right, but it's in the worker's structure, and - * the name could be clearer. gla - */ - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -static void join_workers(apr_thread_t *listener, apr_thread_t **threads) -{ - int i; - apr_status_t rv, thread_rv; - - if (listener) { - int iter; - - /* deal with a rare timing window which affects waking up the - * listener thread... if the signal sent to the listener thread - * is delivered between the time it verifies that the - * listener_may_exit flag is clear and the time it enters a - * blocking syscall, the signal didn't do any good... work around - * that by sleeping briefly and sending it again - */ - - iter = 0; - while (iter < 10 && -#ifdef HAVE_PTHREAD_KILL - pthread_kill(*listener_os_thread, 0) -#else - kill(ap_my_pid, 0) -#endif - == 0) { - /* listener not dead yet */ - apr_sleep(APR_USEC_PER_SEC / 2); - wakeup_listener(); - ++iter; - } - if (iter >= 10) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "the listener thread didn't exit"); - } - else { - rv = apr_thread_join(&thread_rv, listener); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join listener thread"); - } - } - } - - for (i = 0; i < ap_threads_per_child; i++) { - if (threads[i]) { /* if we ever created this thread */ - rv = apr_thread_join(&thread_rv, threads[i]); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join worker " - "thread %d", - i); - } - } - } -} - -static void join_start_thread(apr_thread_t *start_thread_id) -{ - apr_status_t rv, thread_rv; - - start_thread_may_exit = 1; /* tell it to give up in case it is still - * trying to take over slots from a - * previous generation - */ - rv = apr_thread_join(&thread_rv, start_thread_id); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join the start " - "thread"); - } -} - -static void child_main(int child_num_arg) -{ - apr_thread_t **threads; - apr_status_t rv; - thread_starter *ts; - apr_threadattr_t *thread_attr; - apr_thread_t *start_thread_id; - - mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this - * child initializes - */ - ap_my_pid = getpid(); - ap_fatal_signal_child_setup(ap_server_conf); - apr_pool_create(&pchild, pconf); - - /*stuff to do before we switch id's, so we have permissions.*/ - ap_reopen_scoreboard(pchild, NULL, 0); - - rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, - pchild)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize cross-process lock in child"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (unixd_setup_child()) { - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_run_child_init(pchild, ap_server_conf); - - /* done with init critical section */ - - /* Just use the standard apr_setup_signal_thread to block all signals - * from being received. The child processes no longer use signals for - * any communication with the parent process. - */ - rv = apr_setup_signal_thread(); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize signal thread"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (ap_max_requests_per_child) { - requests_this_child = ap_max_requests_per_child; - } - else { - /* coding a value of zero means infinity */ - requests_this_child = INT_MAX; - } - - /* Setup worker threads */ - - /* clear the storage; we may not create all our threads immediately, - * and we want a 0 entry to indicate a thread which was not created - */ - threads = (apr_thread_t **)calloc(1, - sizeof(apr_thread_t *) * ap_threads_per_child); - if (threads == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts)); - - apr_threadattr_create(&thread_attr, pchild); - /* 0 means PTHREAD_CREATE_JOINABLE */ - apr_threadattr_detach_set(thread_attr, 0); - - ts->threads = threads; - ts->listener = NULL; - ts->child_num_arg = child_num_arg; - ts->threadattr = thread_attr; - - rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, - ts, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again if we exit. */ - apr_sleep(10 * APR_USEC_PER_SEC); - clean_child_exit(APEXIT_CHILDFATAL); - } - - mpm_state = AP_MPMQ_RUNNING; - - /* If we are only running in one_process mode, we will want to - * still handle signals. */ - if (one_process) { - /* Block until we get a terminating signal. */ - apr_signal_thread(check_signal); - /* make sure the start thread has finished; signal_threads() - * and join_workers() depend on that - */ - /* XXX join_start_thread() won't be awakened if one of our - * threads encounters a critical error and attempts to - * shutdown this child - */ - join_start_thread(start_thread_id); - signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more - * quickly than the dispatch of the signal thread - * beats the Pipe of Death and the browsers - */ - /* A terminating signal was received. Now join each of the - * workers to clean them up. - * If the worker already exited, then the join frees - * their resources and returns. - * If the worker hasn't exited, then this blocks until - * they have (then cleans up). - */ - join_workers(ts->listener, threads); - } - else { /* !one_process */ - /* remove SIGTERM from the set of blocked signals... if one of - * the other threads in the process needs to take us down - * (e.g., for MaxRequestsPerChild) it will send us SIGTERM - */ - unblock_signal(SIGTERM); - apr_signal(SIGTERM, dummy_signal_handler); - /* Watch for any messages from the parent over the POD */ - while (1) { - rv = ap_mpm_pod_check(pod); - if (rv == AP_NORESTART) { - /* see if termination was triggered while we slept */ - switch(terminate_mode) { - case ST_GRACEFUL: - rv = AP_GRACEFUL; - break; - case ST_UNGRACEFUL: - rv = AP_RESTART; - break; - } - } - if (rv == AP_GRACEFUL || rv == AP_RESTART) { - /* make sure the start thread has finished; - * signal_threads() and join_workers depend on that - */ - join_start_thread(start_thread_id); - signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); - break; - } - } - - if (rv == AP_GRACEFUL) { - /* A terminating signal was received. Now join each of the - * workers to clean them up. - * If the worker already exited, then the join frees - * their resources and returns. - * If the worker hasn't exited, then this blocks until - * they have (then cleans up). - */ - join_workers(ts->listener, threads); - } - } - - free(threads); - - clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); -} - -static int make_child(server_rec *s, int slot) -{ - int pid; - - if (slot + 1 > ap_max_daemons_limit) { - ap_max_daemons_limit = slot + 1; - } - - if (one_process) { - set_signals(); - ap_scoreboard_image->parent[slot].pid = getpid(); - child_main(slot); - } - - if ((pid = fork()) == -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, - "fork: Unable to fork new process"); - - /* fork didn't succeed. Fix the scoreboard or else - * it will say SERVER_STARTING forever and ever - */ - ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); - - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again. */ - apr_sleep(10 * APR_USEC_PER_SEC); - - return -1; - } - - if (!pid) { -#ifdef HAVE_BINDPROCESSOR - /* By default, AIX binds to a single processor. This bit unbinds - * children which will then bind to another CPU. - */ - int status = bindprocessor(BINDPROCESS, (int)getpid(), - PROCESSOR_CLASS_ANY); - if (status != OK) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, - ap_server_conf, - "processor unbind failed %d", status); -#endif - RAISE_SIGSTOP(MAKE_CHILD); - - apr_signal(SIGTERM, just_die); - child_main(slot); - - clean_child_exit(0); - } - /* else */ - ap_scoreboard_image->parent[slot].quiescing = 0; - ap_scoreboard_image->parent[slot].pid = pid; - return 0; -} - -/* start up a bunch of children */ -static void startup_children(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->parent[i].pid != 0) { - continue; - } - if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; - } -} - - -/* - * idle_spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough idle servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int idle_spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (32) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_idle_server_maintenance(void) -{ - int i, j; - int idle_thread_count; - worker_score *ws; - process_score *ps; - int free_length; - int totally_free_length = 0; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead; - int total_non_dead; - - /* initialize the free_list */ - free_length = 0; - - idle_thread_count = 0; - last_non_dead = -1; - total_non_dead = 0; - - for (i = 0; i < ap_daemons_limit; ++i) { - /* Initialization to satisfy the compiler. It doesn't know - * that ap_threads_per_child is always > 0 */ - int status = SERVER_DEAD; - int any_dying_threads = 0; - int any_dead_threads = 0; - int all_dead_threads = 1; - - if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate) - break; - ps = &ap_scoreboard_image->parent[i]; - for (j = 0; j < ap_threads_per_child; j++) { - ws = &ap_scoreboard_image->servers[i][j]; - status = ws->status; - - /* XXX any_dying_threads is probably no longer needed GLA */ - any_dying_threads = any_dying_threads || - (status == SERVER_GRACEFUL); - any_dead_threads = any_dead_threads || (status == SERVER_DEAD); - all_dead_threads = all_dead_threads && - (status == SERVER_DEAD || - status == SERVER_GRACEFUL); - - /* We consider a starting server as idle because we started it - * at least a cycle ago, and if it still hasn't finished starting - * then we're just going to swamp things worse by forking more. - * So we hopefully won't need to fork more if we count it. - * This depends on the ordering of SERVER_READY and SERVER_STARTING. - */ - if (status <= SERVER_READY && status != SERVER_DEAD && - !ps->quiescing && - ps->generation == ap_my_generation && - /* XXX the following shouldn't be necessary if we clean up - * properly after seg faults, but we're not yet GLA - */ - ps->pid != 0) { - ++idle_thread_count; - } - } - if (any_dead_threads && totally_free_length < idle_spawn_rate - && (!ps->pid /* no process in the slot */ - || ps->quiescing)) { /* or at least one is going away */ - if (all_dead_threads) { - /* great! we prefer these, because the new process can - * start more threads sooner. So prioritize this slot - * by putting it ahead of any slots with active threads. - * - * first, make room by moving a slot that's potentially still - * in use to the end of the array - */ - free_slots[free_length] = free_slots[totally_free_length]; - free_slots[totally_free_length++] = i; - } - else { - /* slot is still in use - back of the bus - */ - free_slots[free_length] = i; - } - ++free_length; - } - /* XXX if (!ps->quiescing) is probably more reliable GLA */ - if (!any_dying_threads) { - last_non_dead = i; - ++total_non_dead; - } - } - ap_max_daemons_limit = last_non_dead + 1; - - if (idle_thread_count > max_spare_threads) { - /* Kill off one child */ - ap_mpm_pod_signal(pod, TRUE); - idle_spawn_rate = 1; - } - else if (idle_thread_count < min_spare_threads) { - /* terminate the free list */ - if (free_length == 0) { - /* only report this condition once */ - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, - ap_server_conf, - "server reached MaxClients setting, consider" - " raising the MaxClients setting"); - reported = 1; - } - idle_spawn_rate = 1; - } - else { - if (free_length > idle_spawn_rate) { - free_length = idle_spawn_rate; - } - if (idle_spawn_rate >= 8) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "server seems busy, (you may need " - "to increase StartServers, ThreadsPerChild " - "or Min/MaxSpareThreads), " - "spawning %d children, there are around %d idle " - "threads, and %d total children", free_length, - idle_thread_count, total_non_dead); - } - for (i = 0; i < free_length; ++i) { - make_child(ap_server_conf, free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } - else if (idle_spawn_rate < MAX_SPAWN_RATE) { - idle_spawn_rate *= 2; - } - } - } - else { - idle_spawn_rate = 1; - } -} - -static void server_main_loop(int remaining_children_to_start) -{ - int child_slot; - apr_exit_why_e exitwhy; - int status, processed_status; - apr_proc_t pid; - int i; - - while (!restart_pending && !shutdown_pending) { - ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); - - if (pid.pid != -1) { - processed_status = ap_process_child_status(&pid, exitwhy, status); - if (processed_status == APEXIT_CHILDFATAL) { - shutdown_pending = 1; - child_fatal = 1; - return; - } - /* non-fatal death... note that it's gone in the scoreboard. */ - child_slot = find_child_by_pid(&pid); - if (child_slot >= 0) { - for (i = 0; i < ap_threads_per_child; i++) - ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); - - ap_scoreboard_image->parent[child_slot].pid = 0; - ap_scoreboard_image->parent[child_slot].quiescing = 0; - if (processed_status == APEXIT_CHILDSICK) { - /* resource shortage, minimize the fork rate */ - idle_spawn_rate = 1; - } - else if (remaining_children_to_start - && child_slot < ap_daemons_limit) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - make_child(ap_server_conf, child_slot); - --remaining_children_to_start; - } -#if APR_HAS_OTHER_CHILD - } - else if (apr_proc_other_child_read(&pid, status) == 0) { - /* handled */ -#endif - } - else if (is_graceful) { - /* Great, we've probably just lost a slot in the - * scoreboard. Somehow we don't know about this child. - */ - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, - ap_server_conf, - "long lost child came home! (pid %ld)", - (long)pid.pid); - } - /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ - continue; - } - else if (remaining_children_to_start) { - /* we hit a 1 second timeout in which none of the previous - * generation of children needed to be reaped... so assume - * they're all done, and pick up the slack if any is left. - */ - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - /* In any event we really shouldn't do the code below because - * few of the servers we just started are in the IDLE state - * yet, so we'd mistakenly create an extra server. - */ - continue; - } - - perform_idle_server_maintenance(); - } -} - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - int remaining_children_to_start; - apr_status_t rv; - - ap_log_pid(pconf, ap_pid_fname); - - first_server_limit = server_limit; - first_thread_limit = thread_limit; - if (changed_limit_at_restart) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "WARNING: Attempt to change ServerLimit or ThreadLimit " - "ignored during restart"); - changed_limit_at_restart = 0; - } - - /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, - ap_server_root_relative(_pconf, ap_lock_fname), - ap_my_pid); - - rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, - ap_accept_lock_mech, _pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - -#if APR_USE_SYSVSEM_SERIALIZE - if (ap_accept_lock_mech == APR_LOCK_DEFAULT || - ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#else - if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#endif - rv = unixd_set_proc_mutex_perms(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't set permissions on cross-process lock; " - "check User and Group directives"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - } - - if (!is_graceful) { - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - /* fix the generation number in the global score; we just got a new, - * cleared scoreboard - */ - ap_scoreboard_image->global->running_generation = ap_my_generation; - } - - set_signals(); - /* Don't thrash... */ - if (max_spare_threads < min_spare_threads + ap_threads_per_child) - max_spare_threads = min_spare_threads + ap_threads_per_child; - - /* If we're doing a graceful_restart then we're going to see a lot - * of children exiting immediately when we get into the main loop - * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty - * rapidly... and for each one that exits we'll start a new one until - * we reach at least daemons_min_free. But we may be permitted to - * start more than that, so we'll just keep track of how many we're - * supposed to start up without the 1 second penalty between each fork. - */ - remaining_children_to_start = ap_daemons_to_start; - if (remaining_children_to_start > ap_daemons_limit) { - remaining_children_to_start = ap_daemons_limit; - } - if (!is_graceful) { - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - } - else { - /* give the system some time to recover before kicking into - * exponential mode */ - hold_off_on_exponential_spawning = 10; - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(accept_mutex), - apr_proc_mutex_defname()); -#endif - restart_pending = shutdown_pending = 0; - mpm_state = AP_MPMQ_RUNNING; - - server_main_loop(remaining_children_to_start); - mpm_state = AP_MPMQ_STOPPING; - - if (shutdown_pending) { - /* Time to gracefully shut down: - * Kill child processes, tell them to call child_exit, etc... - * (By "gracefully" we don't mean graceful in the same sense as - * "apachectl graceful" where we allow old connections to finish.) - */ - ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - - if (!child_fatal) { - /* cleanup pid file on normal shutdown */ - const char *pidfile = NULL; - pidfile = ap_server_root_relative (pconf, ap_pid_fname); - if ( pidfile != NULL && unlink(pidfile) == 0) - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "removed PID file %s (pid=%ld)", - pidfile, (long)getpid()); - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, - ap_server_conf, "caught SIGTERM, shutting down"); - } - return 1; - } - - /* we've been told to restart */ - apr_signal(SIGHUP, SIG_IGN); - - if (one_process) { - /* not worth thinking about */ - return 1; - } - - /* advance to the next generation */ - /* XXX: we really need to make sure this new generation number isn't in - * use by any of the children. - */ - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - - if (is_graceful) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); - /* wake up the children...time to die. But we'll have more soon */ - ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE); - - - /* This is mostly for debugging... so that we know what is still - * gracefully dealing with existing request. - */ - - } - else { - /* Kill 'em all. Since the child acts the same on the parents SIGTERM - * and a SIGHUP, we may as well use the same signal, because some user - * pthreads are stealing signals from us left and right. - */ - ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); - - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "SIGHUP received. Attempting to restart"); - } - - return 0; -} - -/* This really should be a post_config hook, but the error log is already - * redirected by that point, so we need to do this in the open_logs phase. - */ -static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - apr_status_t rv; - ap_listen_rec *lr; - - pconf = p; - ap_server_conf = s; - - if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, - NULL, "no listening sockets available, shutting down"); - return DONE; - } - -#if APR_O_NONBLOCK_INHERITED - for(lr = ap_listeners ; lr != NULL ; lr = lr->next) { - apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, 1); - } -#endif /* APR_O_NONBLOCK_INHERITED */ - - if (!one_process) { - if ((rv = ap_mpm_pod_open(pconf, &pod))) { - ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, - "Could not open pipe-of-death."); - return DONE; - } - } - return OK; -} - -static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp) -{ - static int restart_num = 0; - int no_detach, debug, foreground; - ap_directive_t *pdir; - ap_directive_t *max_clients = NULL; - apr_status_t rv; - - mpm_state = AP_MPMQ_STARTING; - - /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ - for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { - if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { - if (!max_clients) { - break; /* we're in the clear, got ThreadsPerChild first */ - } - else { - /* now to swap the data */ - ap_directive_t temp; - - temp.directive = pdir->directive; - temp.args = pdir->args; - /* Make sure you don't change 'next', or you may get loops! */ - /* XXX: first_child, parent, and data can never be set - * for these directives, right? -aaron */ - temp.filename = pdir->filename; - temp.line_num = pdir->line_num; - - pdir->directive = max_clients->directive; - pdir->args = max_clients->args; - pdir->filename = max_clients->filename; - pdir->line_num = max_clients->line_num; - - max_clients->directive = temp.directive; - max_clients->args = temp.args; - max_clients->filename = temp.filename; - max_clients->line_num = temp.line_num; - break; - } - } - else if (!max_clients - && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { - max_clients = pdir; - } - } - - debug = ap_exists_config_define("DEBUG"); - - if (debug) { - foreground = one_process = 1; - no_detach = 0; - } - else { - one_process = ap_exists_config_define("ONE_PROCESS"); - no_detach = ap_exists_config_define("NO_DETACH"); - foreground = ap_exists_config_define("FOREGROUND"); - } - - /* sigh, want this only the second time around */ - if (restart_num++ == 1) { - is_graceful = 0; - - if (!one_process && !foreground) { - rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND - : APR_PROC_DETACH_DAEMONIZE); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "apr_proc_detach failed"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - parent_pid = ap_my_pid = getpid(); - } - - unixd_pre_config(ptemp); - ap_listen_pre_config(); - ap_daemons_to_start = DEFAULT_START_DAEMON; - min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; - max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; - ap_daemons_limit = server_limit; - ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; - ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - return OK; -} - -static void threadpool_hooks(apr_pool_t *p) -{ - /* The worker open_logs phase must run before the core's, or stderr - * will be redirected to a file, and the messages won't print to the - * console. - */ - static const char *const aszSucc[] = {"core.c", NULL}; - one_process = 0; - - ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); - /* we need to set the MPM state before other pre-config hooks use MPM query - * to retrieve it, so register as REALLY_FIRST - */ - ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); -} - -static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_to_start = atoi(arg); - return NULL; -} - -static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - min_spare_threads = atoi(arg); - if (min_spare_threads <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - min_spare_threads = 1; - } - - return NULL; -} - -static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - max_spare_threads = atoi(arg); - return NULL; -} - -static const char *set_max_clients (cmd_parms *cmd, void *dummy, - const char *arg) -{ - int max_clients; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - /* It is ok to use ap_threads_per_child here because we are - * sure that it gets set before MaxClients in the pre_config stage. */ - max_clients = atoi(arg); - if (max_clients < ap_threads_per_child) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients (%d) must be at least as large", - max_clients); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " large as ThreadsPerChild (%d). Automatically", - ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " increasing MaxClients to %d.", - ap_threads_per_child); - max_clients = ap_threads_per_child; - } - ap_daemons_limit = max_clients / ap_threads_per_child; - if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients (%d) is not an integer multiple", - max_clients); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " of ThreadsPerChild (%d), lowering MaxClients to %d", - ap_threads_per_child, - ap_daemons_limit * ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " for a maximum of %d child processes,", - ap_daemons_limit); - max_clients = ap_daemons_limit * ap_threads_per_child; - } - if (ap_daemons_limit > server_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients of %d would require %d servers,", - max_clients, ap_daemons_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " and would exceed the ServerLimit value of %d.", - server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " Automatically lowering MaxClients to %d. To increase,", - server_limit * ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " please see the ServerLimit directive."); - ap_daemons_limit = server_limit; - } - else if (ap_daemons_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require MaxClients > 0, setting to 1"); - ap_daemons_limit = 1; - } - return NULL; -} - -static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_per_child = atoi(arg); - if (ap_threads_per_child > thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " - "value of %d", ap_threads_per_child, - thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "threads, lowering ThreadsPerChild to %d. To increase, please" - " see the", thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " ThreadLimit directive."); - ap_threads_per_child = thread_limit; - } - else if (ap_threads_per_child < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadsPerChild > 0, setting to 1"); - ap_threads_per_child = 1; - } - return NULL; -} - -static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_server_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_server_limit = atoi(arg); - /* you cannot change ServerLimit across a restart; ignore - * any such attempts - */ - if (first_server_limit && - tmp_server_limit != server_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - server_limit = tmp_server_limit; - - if (server_limit > MAX_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ServerLimit of %d exceeds compile time limit " - "of %d servers,", server_limit, MAX_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); - server_limit = MAX_SERVER_LIMIT; - } - else if (server_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ServerLimit > 0, setting to 1"); - server_limit = 1; - } - return NULL; -} - -static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_thread_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_thread_limit = atoi(arg); - /* you cannot change ThreadLimit across a restart; ignore - * any such attempts - */ - if (first_thread_limit && - tmp_thread_limit != thread_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - thread_limit = tmp_thread_limit; - - if (thread_limit > MAX_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadLimit of %d exceeds compile time limit " - "of %d servers,", thread_limit, MAX_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); - thread_limit = MAX_THREAD_LIMIT; - } - else if (thread_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadLimit > 0, setting to 1"); - thread_limit = 1; - } - return NULL; -} - -static const command_rec threadpool_cmds[] = { -UNIX_DAEMON_COMMANDS, -LISTEN_COMMANDS, -AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, - "Number of child processes launched at server startup"), -AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, - "Minimum number of idle children, to handle request spikes"), -AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, - "Maximum number of idle children"), -AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, - "Maximum number of children alive at the same time"), -AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, - "Number of threads each child creates"), -AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, - "Maximum value of MaxClients for this run of Apache"), -AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, - "Maximum worker threads in a server for this run of Apache"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_threadpool_module = { - MPM20_MODULE_STUFF, - ap_mpm_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - threadpool_cmds, /* command apr_table_t */ - threadpool_hooks /* register_hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/monitoring-services.txt b/rubbos/app/httpd-2.0.64/server/mpm/monitoring-services.txt deleted file mode 100644 index 24665890..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/monitoring-services.txt +++ /dev/null @@ -1,94 +0,0 @@ -From: William A. Rowe, Jr. -Date: June 7th '00 -Subject: service monitoring in Apache 1.3.13 - -The concept for a taskbar monitor has been thrown around -for a very long while. 1.3.13 introduced Win9x services, -and that added fuel to the mix. Here are some sideband -observations I've made for other developers... - -About Apache as a console, don't start Apache hidden without -any command line arguments if you want to launch it yourself -in a hidden window (it will do the classic test for -AllocConsole/FreeConsole)... drop in some arguments such as -the -f or -r option and it will fly without thinking it is a -service under 9x and NT. - -Rule two, don't use --ntservice as an argument, ever. Only -the Windows NT Service Control Manager is allowed to pass that -flag, and only that flag, when it runs Apache.exe. Do use ---ntservice as the sole argument to the executable name if -you are installing an Apache NT service yourself. - -Rule three, use -k start and -n name when maintaining the -HKLM/Software/Microsoft/Windows/CurrentVersion/RunServices -list, since there is no other way for Apache to know what -the service is named :) And look at any 9x installed service's -RunServices entry in the registry for the start service semantic. - -Rule four, use the WinNT Service Control Manager exclusively -for starting, stopping and restarting Apache as an NT service. -The restart signal is the value 128, as documented in service.h -and service.c - this will continue to work in Apache 2.0. If -it fails, you are handling an older version (pre 1.3.13) of -Apache, and need to stop and then start the service instead. - -Rule five, use the legacy pid-named events to signal Win9x -service Apache to restart and stop the service. But don't -bother looking for httpd.pid files... you can get the pid -right from the hidden service control window. Apache 1.3.13 -and 2.x create a hidden window named for the name of the -service (without the spaces), with a window class of -"ApacheWin95ServiceMonitor", so can use FindWindow to track -down running Win9x services. See the service.c code for how -I accomplished this pretty simply in the -k stop/-k restart -handler. - -Taskbar Monitor App -------------------- - -Basic requirements: a C code application using strictly the -Win32 API, and not MFC or other Win32 frameworks. Could use -the service.c module to share some basic functions. That -module could be extended in Apache 2.0 to make this all easier. - -I think we are looking for an external app that simply acts -as a monitor or allows a stopped service to be started. If -the user logs off, we loose the monitor app, but installed as -a shortcut in the Start group or in the registry key -HKLM/Software/Microsoft/Windows/CurrentVersion/Run -we will be just fine. I'd like to see the monitor run only -one instance to monitor all running services, for memory -and resource conservation. - -I was thinking that the hover/iconbar title would tell them -"Test service is running", or "Test service is stopped". -If they left click, they could stop or restart, or simply -start if it is stopped. There could be a preference that -each service doesn't get it's own individual task icon unless -it is running, if it is a manual start service (or missing -from the RunServices list, which is the equivilant under 9x). - -If a specific service is set to Auto start or is in the -RunServices Win9x registry key, we must show them the stopped -icon, of course. We might also keep the icon for any running -service that stops abruptly. But there could be a 'single -icon' option for the taskbar icon monitor that says show only -a single status icon, for simplicity if the administrator runs -many Apache services. - -But I was hoping that any right click would provide a menu -of all Apache services with their status. e.g. - Test service is stopped - Apache_2 service is running - MyWeb service is running -and each would do the logical submenu, same as if that -specific taskbar icon were left clicked, offering to start or -offering to stop or restart the server, as appropriate. - -Finally, to identify all installed Apache services, just query -the registry key HKLM\SYSTEM\CurrentControlSet\Services for any -key that has the ImagePath value of "...\Apache.exe"... (quotes -are significant here, if the leading quote is ommitted the -entire string ends with the text \Apache.exe - based on Apache's -own service installer in every released version.) diff --git a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/Makefile.in deleted file mode 100644 index 38e598ed..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libmpmt_os2.la -LTLIBRARY_SOURCES = mpmt_os2.c mpmt_os2_child.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/config5.m4 b/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/config5.m4 deleted file mode 100644 index b27c296d..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/config5.m4 +++ /dev/null @@ -1,5 +0,0 @@ -if test "$MPM_NAME" = "mpmt_os2" ; then - AC_CACHE_SAVE - APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) - APR_ADDTO(CFLAGS,-Zmt) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpm.h deleted file mode 100644 index 15f341dd..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpm.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_MPMT_OS2_H -#define APACHE_MPM_MPMT_OS2_H - -#define MPMT_OS2_MPM - -#include "httpd.h" -#include "mpm_default.h" -#include "scoreboard.h" - -#define MPM_NAME "MPMT_OS2" - -extern server_rec *ap_server_conf; -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK -#define AP_MPM_WANT_SET_MAX_MEM_FREE - -#endif /* APACHE_MPM_MPMT_OS2_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpm_default.h deleted file mode 100644 index d45b2ce2..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpm_default.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of servers processes to spawn off by default - */ -#ifndef DEFAULT_START_DAEMON -#define DEFAULT_START_DAEMON 2 -#endif - -/* Maximum number of *free* server threads --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_SPARE_THREAD -#define DEFAULT_MAX_SPARE_THREAD 10 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_SPARE_THREAD -#define DEFAULT_MIN_SPARE_THREAD 5 -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpmt_os2.c b/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpmt_os2.c deleted file mode 100644 index 2c7f57bf..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpmt_os2.c +++ /dev/null @@ -1,577 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Multi-process, multi-threaded MPM for OS/2 - * - * Server consists of - * - a main, parent process - * - a small, static number of child processes - * - * The parent process's job is to manage the child processes. This involves - * spawning children as required to ensure there are always ap_daemons_to_start - * processes accepting connections. - * - * Each child process consists of a a pool of worker threads and a - * main thread that accepts connections & passes them to the workers via - * a work queue. The worker thread pool is dynamic, managed by a maintanence - * thread so that the number of idle threads is kept between - * min_spare_threads & max_spare_threads. - * - */ - -/* - Todo list - - Enforce MaxClients somehow -*/ -#define CORE_PRIVATE -#define INCL_NOPMAPI -#define INCL_DOS -#define INCL_DOSERRORS - -#include "ap_config.h" -#include "httpd.h" -#include "mpm_default.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "mpm.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "apr_portable.h" -#include "mpm_common.h" -#include "apr_strings.h" -#include <os2.h> -#include <process.h> - -/* We don't need many processes, - * they're only for redundancy in the event of a crash - */ -#define HARD_SERVER_LIMIT 10 - -/* Limit on the total number of threads per process - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 256 -#endif - -server_rec *ap_server_conf; -static apr_pool_t *pconf = NULL; /* Pool for config stuff */ -static const char *ap_pid_fname=NULL; - -/* Config globals */ -static int one_process = 0; -static int ap_daemons_to_start = 0; -static int ap_thread_limit = 0; -static int ap_max_requests_per_child = 0; -int ap_min_spare_threads = 0; -int ap_max_spare_threads = 0; - -/* Keep track of a few interesting statistics */ -int ap_max_daemons_limit = -1; - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful = 0; -ap_generation_t volatile ap_my_generation=0; /* Used by the scoreboard */ -static int is_parent_process=TRUE; -HMTX ap_mpm_accept_mutex = 0; - -/* An array of these is stored in a shared memory area for passing - * sockets from the parent to child processes - */ -typedef struct { - struct sockaddr_in name; - apr_os_sock_t listen_fd; -} listen_socket_t; - -typedef struct { - HMTX accept_mutex; - listen_socket_t listeners[1]; -} parent_info_t; - -static char master_main(); -static void spawn_child(int slot); -void ap_mpm_child_main(apr_pool_t *pconf); -static void set_signals(); - - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) -{ - char *listener_shm_name; - parent_info_t *parent_info; - ULONG rc; - pconf = _pconf; - ap_server_conf = s; - restart_pending = 0; - - DosSetMaxFH(ap_thread_limit * 2); - listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getppid()); - rc = DosGetNamedSharedMem((PPVOID)&parent_info, listener_shm_name, PAG_READ); - is_parent_process = rc != 0; - ap_scoreboard_fname = apr_psprintf(pconf, "/sharemem/httpd/scoreboard.%d", is_parent_process ? getpid() : getppid()); - - if (rc == 0) { - /* Child process */ - ap_listen_rec *lr; - int num_listeners = 0; - - ap_mpm_accept_mutex = parent_info->accept_mutex; - - /* Set up a default listener if necessary */ - if (ap_listeners == NULL) { - ap_listen_rec *lr = apr_pcalloc(s->process->pool, sizeof(ap_listen_rec)); - ap_listeners = lr; - apr_sockaddr_info_get(&lr->bind_addr, "0.0.0.0", APR_UNSPEC, - DEFAULT_HTTP_PORT, 0, s->process->pool); - apr_socket_create(&lr->sd, lr->bind_addr->family, - SOCK_STREAM, s->process->pool); - } - - for (lr = ap_listeners; lr; lr = lr->next) { - apr_sockaddr_t *sa; - apr_os_sock_put(&lr->sd, &parent_info->listeners[num_listeners].listen_fd, pconf); - apr_socket_addr_get(&sa, APR_LOCAL, lr->sd); - num_listeners++; - } - - DosFreeMem(parent_info); - - /* Do the work */ - ap_mpm_child_main(pconf); - - /* Outta here */ - return 1; - } - else { - /* Parent process */ - char restart; - is_parent_process = TRUE; - - if (ap_setup_listeners(ap_server_conf) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, - "no listening sockets available, shutting down"); - return 1; - } - - ap_log_pid(pconf, ap_pid_fname); - - restart = master_main(); - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - - if (!restart) { - const char *pidfile = ap_server_root_relative(pconf, ap_pid_fname); - - if (pidfile != NULL && remove(pidfile) == 0) { - ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, - ap_server_conf, "removed PID file %s (pid=%d)", - pidfile, getpid()); - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "caught SIGTERM, shutting down"); - return 1; - } - } /* Parent process */ - - return 0; /* Restart */ -} - - - -/* Main processing of the parent process - * returns TRUE if restarting - */ -static char master_main() -{ - server_rec *s = ap_server_conf; - ap_listen_rec *lr; - parent_info_t *parent_info; - char *listener_shm_name; - int listener_num, num_listeners, slot; - ULONG rc; - - printf("%s \n", ap_get_server_version()); - set_signals(); - - if (ap_setup_listeners(ap_server_conf) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, - "no listening sockets available, shutting down"); - return FALSE; - } - - /* Allocate a shared memory block for the array of listeners */ - for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) { - num_listeners++; - } - - listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getpid()); - rc = DosAllocSharedMem((PPVOID)&parent_info, listener_shm_name, - sizeof(parent_info_t) + num_listeners * sizeof(listen_socket_t), - PAG_READ|PAG_WRITE|PAG_COMMIT); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s, - "failure allocating shared memory, shutting down"); - return FALSE; - } - - /* Store the listener sockets in the shared memory area for our children to see */ - for (listener_num = 0, lr = ap_listeners; lr; lr = lr->next, listener_num++) { - apr_os_sock_get(&parent_info->listeners[listener_num].listen_fd, lr->sd); - } - - /* Create mutex to prevent multiple child processes from detecting - * a connection with apr_poll() - */ - - rc = DosCreateMutexSem(NULL, &ap_mpm_accept_mutex, DC_SEM_SHARED, FALSE); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s, - "failure creating accept mutex, shutting down"); - return FALSE; - } - - parent_info->accept_mutex = ap_mpm_accept_mutex; - - /* Allocate shared memory for scoreboard */ - if (ap_scoreboard_image == NULL) { - void *sb_mem; - rc = DosAllocSharedMem(&sb_mem, ap_scoreboard_fname, - ap_calc_scoreboard_size(), - PAG_COMMIT|PAG_READ|PAG_WRITE); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "unable to allocate shared memory for scoreboard , exiting"); - return FALSE; - } - - ap_init_scoreboard(sb_mem); - } - - ap_scoreboard_image->global->restart_time = apr_time_now(); - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(accept_mutex), - apr_proc_mutex_defname()); -#endif - if (one_process) { - ap_scoreboard_image->parent[0].pid = getpid(); - ap_mpm_child_main(pconf); - return FALSE; - } - - while (!restart_pending && !shutdown_pending) { - RESULTCODES proc_rc; - PID child_pid; - int active_children = 0; - - /* Count number of active children */ - for (slot=0; slot < HARD_SERVER_LIMIT; slot++) { - active_children += ap_scoreboard_image->parent[slot].pid != 0 && - !ap_scoreboard_image->parent[slot].quiescing; - } - - /* Spawn children if needed */ - for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) { - if (ap_scoreboard_image->parent[slot].pid == 0) { - spawn_child(slot); - active_children++; - } - } - - rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0); - - if (rc == 0) { - /* A child has terminated, remove its scoreboard entry & terminate if necessary */ - for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++); - - if (slot < HARD_SERVER_LIMIT) { - ap_scoreboard_image->parent[slot].pid = 0; - ap_scoreboard_image->parent[slot].quiescing = 0; - - if (proc_rc.codeTerminate == TC_EXIT) { - /* Child terminated normally, check its exit code and - * terminate server if child indicates a fatal error - */ - if (proc_rc.codeResult == APEXIT_CHILDFATAL) - break; - } - } - } else if (rc == ERROR_CHILD_NOT_COMPLETE) { - /* No child exited, lets sleep for a while.... */ - apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); - } - } - - /* Signal children to shut down, either gracefully or immediately */ - for (slot=0; slot<HARD_SERVER_LIMIT; slot++) { - kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM); - } - - DosFreeMem(parent_info); - return restart_pending; -} - - - -static void spawn_child(int slot) -{ - PPIB ppib; - PTIB ptib; - char fail_module[100]; - char progname[CCHMAXPATH]; - RESULTCODES proc_rc; - ULONG rc; - - ap_scoreboard_image->parent[slot].generation = ap_my_generation; - DosGetInfoBlocks(&ptib, &ppib); - DosQueryModuleName(ppib->pib_hmte, sizeof(progname), progname); - rc = DosExecPgm(fail_module, sizeof(fail_module), EXEC_ASYNCRESULT, - ppib->pib_pchcmd, NULL, &proc_rc, progname); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "error spawning child, slot %d", slot); - } - - if (ap_max_daemons_limit < slot) { - ap_max_daemons_limit = slot; - } - - ap_scoreboard_image->parent[slot].pid = proc_rc.codeTerminate; -} - - - -/* Signal handling routines */ - -static void sig_term(int sig) -{ - shutdown_pending = 1; - signal(SIGTERM, SIG_DFL); -} - - - -static void sig_restart(int sig) -{ - if (sig == SIGUSR1) { - is_graceful = 1; - } - - restart_pending = 1; -} - - - -static void set_signals() -{ - struct sigaction sa; - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = sig_term; - - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); - - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); - - sa.sa_handler = sig_restart; - - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); - if (sigaction(SIGUSR1, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGUSR1)"); -} - - - -/* Enquiry functions used get MPM status info */ - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch (query_code) { - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_max_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = HARD_SERVER_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = HARD_THREAD_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - - - -int ap_graceful_stop_signalled(void) -{ - return is_graceful; -} - - - -/* Configuration handling stuff */ - -static int mpmt_os2_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) -{ - one_process = ap_exists_config_define("ONE_PROCESS") || - ap_exists_config_define("DEBUG"); - is_graceful = 0; - ap_listen_pre_config(); - ap_daemons_to_start = DEFAULT_START_DAEMON; - ap_thread_limit = HARD_THREAD_LIMIT; - ap_pid_fname = DEFAULT_PIDLOG; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; - ap_min_spare_threads = DEFAULT_MIN_SPARE_THREAD; - ap_max_spare_threads = DEFAULT_MAX_SPARE_THREAD; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - return OK; -} - - - -static void mpmt_os2_hooks(apr_pool_t *p) -{ - ap_hook_pre_config(mpmt_os2_pre_config, NULL, NULL, APR_HOOK_MIDDLE); -} - - - -static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - ap_daemons_to_start = atoi(arg); - return NULL; -} - - - -static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - ap_min_spare_threads = atoi(arg); - - if (ap_min_spare_threads <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - ap_min_spare_threads = 1; - } - - return NULL; -} - - - -static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - - if (err != NULL) { - return err; - } - - ap_max_spare_threads = atoi(arg); - return NULL; -} - - - -static const char *ignore_cmd(cmd_parms *cmd, void *dummy, const char *arg) -{ - return NULL; -} - - - -static const command_rec mpmt_os2_cmds[] = { -LISTEN_COMMANDS, -AP_INIT_TAKE1( "StartServers", set_daemons_to_start, NULL, RSRC_CONF, - "Number of child processes launched at server startup" ), -AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, - "Minimum number of idle children, to handle request spikes"), -AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, - "Maximum number of idle children"), -AP_INIT_TAKE1("User", ignore_cmd, NULL, RSRC_CONF, - "Not applicable on this platform"), -AP_INIT_TAKE1("Group", ignore_cmd, NULL, RSRC_CONF, - "Not applicable on this platform"), -AP_INIT_TAKE1("ScoreBoardFile", ignore_cmd, NULL, RSRC_CONF, \ - "Not applicable on this platform"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_mpmt_os2_module = { - MPM20_MODULE_STUFF, - NULL, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - mpmt_os2_cmds, /* command apr_table_t */ - mpmt_os2_hooks, /* register_hooks */ -}; diff --git a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpmt_os2_child.c b/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpmt_os2_child.c deleted file mode 100644 index 1b47cae0..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/mpmt_os2/mpmt_os2_child.c +++ /dev/null @@ -1,497 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define CORE_PRIVATE -#define INCL_NOPMAPI -#define INCL_DOS -#define INCL_DOSERRORS - -#include "ap_config.h" -#include "httpd.h" -#include "mpm_default.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "mpm.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "apr_portable.h" -#include "apr_poll.h" -#include "mpm_common.h" -#include "apr_strings.h" -#include <os2.h> -#include <process.h> - -/* XXXXXX move these to header file private to this MPM */ - -/* We don't need many processes, - * they're only for redundancy in the event of a crash - */ -#define HARD_SERVER_LIMIT 10 - -/* Limit on the total number of threads per process - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 256 -#endif - -#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) - -typedef struct { - apr_pool_t *pconn; - apr_socket_t *conn_sd; -} worker_args_t; - -#define WORKTYPE_CONN 0 -#define WORKTYPE_EXIT 1 - -static apr_pool_t *pchild = NULL; -static int child_slot; -static int shutdown_pending = 0; -extern int ap_my_generation; -static int volatile is_graceful = 1; -HEV shutdown_event; /* signaled when this child is shutting down */ - -/* grab some MPM globals */ -extern int ap_min_spare_threads; -extern int ap_max_spare_threads; -extern HMTX ap_mpm_accept_mutex; - -static void worker_main(void *vpArg); -static void clean_child_exit(int code); -static void set_signals(); -static void server_maintenance(void *vpArg); - - -static void clean_child_exit(int code) -{ - if (pchild) { - apr_pool_destroy(pchild); - } - - exit(code); -} - - - -void ap_mpm_child_main(apr_pool_t *pconf) -{ - ap_listen_rec *lr = NULL; - ap_listen_rec *first_lr = NULL; - int requests_this_child = 0; - apr_socket_t *sd = ap_listeners->sd; - int nsds, rv = 0; - unsigned long ulTimes; - int my_pid = getpid(); - ULONG rc, c; - HQUEUE workq; - apr_pollfd_t *pollset; - int num_listeners; - TID server_maint_tid; - void *sb_mem; - - /* Stop Ctrl-C/Ctrl-Break signals going to child processes */ - DosSetSignalExceptionFocus(0, &ulTimes); - set_signals(); - - /* Create pool for child */ - apr_pool_create(&pchild, pconf); - - ap_run_child_init(pchild, ap_server_conf); - - /* Create an event semaphore used to trigger other threads to shutdown */ - rc = DosCreateEventSem(NULL, &shutdown_event, 0, FALSE); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "unable to create shutdown semaphore, exiting"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - /* Gain access to the scoreboard. */ - rc = DosGetNamedSharedMem(&sb_mem, ap_scoreboard_fname, - PAG_READ|PAG_WRITE); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "scoreboard not readable in child, exiting"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_calc_scoreboard_size(); - ap_init_scoreboard(sb_mem); - - /* Gain access to the accpet mutex */ - rc = DosOpenMutexSem(NULL, &ap_mpm_accept_mutex); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "accept mutex couldn't be accessed in child, exiting"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - /* Find our pid in the scoreboard so we know what slot our parent allocated us */ - for (child_slot = 0; ap_scoreboard_image->parent[child_slot].pid != my_pid && child_slot < HARD_SERVER_LIMIT; child_slot++); - - if (child_slot == HARD_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, - "child pid not found in scoreboard, exiting"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_my_generation = ap_scoreboard_image->parent[child_slot].generation; - memset(ap_scoreboard_image->servers[child_slot], 0, sizeof(worker_score) * HARD_THREAD_LIMIT); - - /* Set up an OS/2 queue for passing connections & termination requests - * to worker threads - */ - rc = DosCreateQueue(&workq, QUE_FIFO, apr_psprintf(pchild, "/queues/httpd/work.%d", my_pid)); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "unable to create work queue, exiting"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - /* Create initial pool of worker threads */ - for (c = 0; c < ap_min_spare_threads; c++) { -// ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c); - } - - /* Start maintenance thread */ - server_maint_tid = _beginthread(server_maintenance, NULL, 32768, NULL); - - /* Set up poll */ - for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) { - num_listeners++; - } - - apr_poll_setup(&pollset, num_listeners, pchild); - - for (lr = ap_listeners; lr; lr = lr->next) { - apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); - } - - /* Main connection accept loop */ - do { - apr_pool_t *pconn; - worker_args_t *worker_args; - - apr_pool_create(&pconn, pchild); - worker_args = apr_palloc(pconn, sizeof(worker_args_t)); - worker_args->pconn = pconn; - - if (num_listeners == 1) { - rv = apr_accept(&worker_args->conn_sd, ap_listeners->sd, pconn); - } else { - rc = DosRequestMutexSem(ap_mpm_accept_mutex, SEM_INDEFINITE_WAIT); - - if (shutdown_pending) { - DosReleaseMutexSem(ap_mpm_accept_mutex); - break; - } - - rv = APR_FROM_OS_ERROR(rc); - - if (rv == APR_SUCCESS) { - rv = apr_poll(pollset, num_listeners, &nsds, -1); - DosReleaseMutexSem(ap_mpm_accept_mutex); - } - - if (rv == APR_SUCCESS) { - if (first_lr == NULL) { - first_lr = ap_listeners; - } - - lr = first_lr; - - do { - apr_int16_t event; - - apr_poll_revents_get(&event, lr->sd, pollset); - - if (event == APR_POLLIN) { - apr_sockaddr_t *sa; - apr_port_t port; - apr_socket_addr_get(&sa, APR_LOCAL, lr->sd); - apr_sockaddr_port_get(&port, sa); - first_lr = lr->next; - break; - } - lr = lr->next; - - if (!lr) { - lr = ap_listeners; - } - } while (lr != first_lr); - - if (lr == first_lr) { - continue; - } - - sd = lr->sd; - rv = apr_accept(&worker_args->conn_sd, sd, pconn); - } - } - - if (rv != APR_SUCCESS) { - if (!APR_STATUS_IS_EINTR(rv)) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, - "apr_accept"); - clean_child_exit(APEXIT_CHILDFATAL); - } - } else { - DosWriteQueue(workq, WORKTYPE_CONN, sizeof(worker_args_t), worker_args, 0); - requests_this_child++; - } - - if (ap_max_requests_per_child != 0 && requests_this_child >= ap_max_requests_per_child) - break; - } while (!shutdown_pending && ap_my_generation == ap_scoreboard_image->global->running_generation); - - ap_scoreboard_image->parent[child_slot].quiescing = 1; - DosPostEventSem(shutdown_event); - DosWaitThread(&server_maint_tid, DCWW_WAIT); - - if (is_graceful) { - char someleft; - - /* tell our worker threads to exit */ - for (c=0; c<HARD_THREAD_LIMIT; c++) { - if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) { - DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); - } - } - - do { - someleft = 0; - - for (c=0; c<HARD_THREAD_LIMIT; c++) { - if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) { - someleft = 1; - DosSleep(1000); - break; - } - } - } while (someleft); - } else { - DosPurgeQueue(workq); - - for (c=0; c<HARD_THREAD_LIMIT; c++) { - if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) { - DosKillThread(ap_scoreboard_image->servers[child_slot][c].tid); - } - } - } - - apr_pool_destroy(pchild); -} - - - -void add_worker() -{ - int thread_slot; - - /* Find a free thread slot */ - for (thread_slot=0; thread_slot < HARD_THREAD_LIMIT; thread_slot++) { - if (ap_scoreboard_image->servers[child_slot][thread_slot].status == SERVER_DEAD) { - ap_scoreboard_image->servers[child_slot][thread_slot].status = SERVER_STARTING; - ap_scoreboard_image->servers[child_slot][thread_slot].tid = - _beginthread(worker_main, NULL, 128*1024, (void *)thread_slot); - break; - } - } -} - - - -ULONG APIENTRY thread_exception_handler(EXCEPTIONREPORTRECORD *pReportRec, - EXCEPTIONREGISTRATIONRECORD *pRegRec, - CONTEXTRECORD *pContext, - PVOID p) -{ - int c; - - if (pReportRec->fHandlerFlags & EH_NESTED_CALL) { - return XCPT_CONTINUE_SEARCH; - } - - if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION || - pReportRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, - "caught exception in worker thread, initiating child shutdown pid=%d", getpid()); - for (c=0; c<HARD_THREAD_LIMIT; c++) { - if (ap_scoreboard_image->servers[child_slot][c].tid == _gettid()) { - ap_scoreboard_image->servers[child_slot][c].status = SERVER_DEAD; - break; - } - } - - /* Shut down process ASAP, it could be quite unhealthy & leaking resources */ - shutdown_pending = 1; - ap_scoreboard_image->parent[child_slot].quiescing = 1; - kill(getpid(), SIGHUP); - DosUnwindException(UNWIND_ALL, 0, 0); - } - - return XCPT_CONTINUE_SEARCH; -} - - - -static void worker_main(void *vpArg) -{ - long conn_id; - conn_rec *current_conn; - apr_pool_t *pconn; - apr_allocator_t *allocator; - apr_bucket_alloc_t *bucket_alloc; - worker_args_t *worker_args; - HQUEUE workq; - PID owner; - int rc; - REQUESTDATA rd; - ULONG len; - BYTE priority; - int thread_slot = (int)vpArg; - EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler }; - ap_sb_handle_t *sbh; - - /* Trap exceptions in this thread so we don't take down the whole process */ - DosSetExceptionHandler( ®_rec ); - - rc = DosOpenQueue(&owner, &workq, - apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "unable to open work queue, exiting"); - ap_scoreboard_image->servers[child_slot][thread_slot].tid = 0; - } - - conn_id = ID_FROM_CHILD_THREAD(child_slot, thread_slot); - ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_READY, - NULL); - - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - bucket_alloc = apr_bucket_alloc_create_ex(allocator); - - while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE), - rc == 0 && rd.ulData != WORKTYPE_EXIT) { - pconn = worker_args->pconn; - ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot); - current_conn = ap_run_create_connection(pconn, ap_server_conf, - worker_args->conn_sd, conn_id, - sbh, bucket_alloc); - - if (current_conn) { - ap_process_connection(current_conn, worker_args->conn_sd); - ap_lingering_close(current_conn); - } - - apr_pool_destroy(pconn); - ap_update_child_status_from_indexes(child_slot, thread_slot, - SERVER_READY, NULL); - } - - ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_DEAD, - NULL); - - apr_bucket_alloc_destroy(bucket_alloc); - apr_allocator_destroy(allocator); -} - - - -static void server_maintenance(void *vpArg) -{ - int num_idle, num_needed; - ULONG num_pending = 0; - int threadnum; - HQUEUE workq; - ULONG rc; - PID owner; - - rc = DosOpenQueue(&owner, &workq, - apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); - - if (rc) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, - "unable to open work queue in maintenance thread"); - return; - } - - do { - for (num_idle=0, threadnum=0; threadnum < HARD_THREAD_LIMIT; threadnum++) { - num_idle += ap_scoreboard_image->servers[child_slot][threadnum].status == SERVER_READY; - } - - DosQueryQueue(workq, &num_pending); - num_needed = ap_min_spare_threads - num_idle + num_pending; - - if (num_needed > 0) { - for (threadnum=0; threadnum < num_needed; threadnum++) { - add_worker(); - } - } - - if (num_idle - num_pending > ap_max_spare_threads) { - DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); - } - } while (DosWaitEventSem(shutdown_event, 500) == ERROR_TIMEOUT); -} - - - -/* Signal handling routines */ - -static void sig_term(int sig) -{ - shutdown_pending = 1; - is_graceful = 0; - signal(SIGTERM, SIG_DFL); -} - - - -static void sig_hup(int sig) -{ - shutdown_pending = 1; - is_graceful = 1; -} - - - -static void set_signals() -{ - struct sigaction sa; - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = sig_term; - - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); - - sa.sa_handler = sig_hup; - - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); -} diff --git a/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm.h deleted file mode 100644 index 4b9a8392..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "scoreboard.h" - -#ifndef APACHE_MPM_THREADED_H -#define APACHE_MPM_THREADED_H - -#define THREADED_MPM - -#define MPM_NAME "NetWare_Threaded" - -/*#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES - #define AP_MPM_WANT_WAIT_OR_TIMEOUT - #define AP_MPM_WANT_PROCESS_CHILD_STATUS - #define AP_MPM_WANT_SET_PIDFILE - #define AP_MPM_WANT_SET_SCOREBOARD - #define AP_MPM_WANT_SET_LOCKFILE -*/ -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_MAX_MEM_FREE -#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK -/*#define AP_MPM_WANT_SET_COREDUMPDIR - #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -*/ - -#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) - -extern int ap_threads_per_child; -extern int ap_thread_stack_size; -extern int ap_max_workers_limit; -extern server_rec *ap_server_conf; - -#endif /* APACHE_MPM_THREADED_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm_default.h deleted file mode 100644 index 397f5511..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm_default.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of servers to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_DAEMON -#define DEFAULT_START_DAEMON 1 -#endif - -/* Maximum number of *free* server processes --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_FREE_DAEMON -#define DEFAULT_MAX_FREE_DAEMON 1 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_FREE_DAEMON -#define DEFAULT_MIN_FREE_DAEMON 1 -#endif - -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 2048 -#endif - -#ifndef DEFAULT_THREADS_PER_CHILD -#define DEFAULT_THREADS_PER_CHILD 50 -#endif - -/* Number of threads to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_THREADS -#define DEFAULT_START_THREADS DEFAULT_THREADS_PER_CHILD -#endif - -/* Maximum number of *free* threads --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_FREE_THREADS -#define DEFAULT_MAX_FREE_THREADS 100 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_FREE_THREADS -#define DEFAULT_MIN_FREE_THREADS 10 -#endif - -/* Check for definition of DEFAULT_REL_RUNTIMEDIR */ -#ifndef DEFAULT_REL_RUNTIMEDIR -#define DEFAULT_REL_RUNTIMEDIR "logs" -#endif - -/* File used for accept locking, when we use a file */ -/*#ifndef DEFAULT_LOCKFILE - #define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" - #endif -*/ - -/* Where the main/parent process's pid is logged */ -/*#ifndef DEFAULT_PIDLOG - #define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" - #endif -*/ - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 0 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm_netware.c b/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm_netware.c deleted file mode 100644 index f3eb227c..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/netware/mpm_netware.c +++ /dev/null @@ -1,1295 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * httpd.c: simple http daemon for answering WWW file requests - * - * - * 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3) - * - * 03-06-95 blong - * changed server number for child-alone processes to 0 and changed name - * of processes - * - * 03-10-95 blong - * Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu) - * including set group before fork, and call gettime before to fork - * to set up libraries. - * - * 04-14-95 rst / rh - * Brandon's code snarfed from NCSA 1.4, but tinkered to work with the - * Apache server, and also to have child processes do accept() directly. - * - * April-July '95 rst - * Extensive rework for Apache. - */ - -#include "apr.h" -#include "apr_portable.h" -#include "apr_strings.h" -#include "apr_thread_proc.h" -#include "apr_signal.h" -#include "apr_tables.h" -#include "apr_getopt.h" -#include "apr_thread_mutex.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "mpm_default.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "scoreboard.h" -#include "ap_mpm.h" -#include "mpm_common.h" -#include "ap_listen.h" -#include "ap_mmn.h" - -#ifdef HAVE_TIME_H -#include <time.h> -#endif - -#include <signal.h> - -#include <netware.h> -#include <nks/netware.h> -#include <library.h> -#include <screen.h> - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_SERVER_LIMIT -#define HARD_SERVER_LIMIT 1 -#endif - -#define WORKER_DEAD SERVER_DEAD -#define WORKER_STARTING SERVER_STARTING -#define WORKER_READY SERVER_READY -#define WORKER_IDLE_KILL SERVER_IDLE_KILL - -/* config globals */ - -int ap_threads_per_child=0; /* Worker threads per child */ -int ap_thread_stack_size=65536; -static int ap_threads_to_start=0; -static int ap_threads_min_free=0; -static int ap_threads_max_free=0; -static int ap_threads_limit=0; -static int mpm_state = AP_MPMQ_STARTING; - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with MaxClients changes across SIGWINCH restarts. We use this - * value to optimize routines that have to scan the entire scoreboard. - */ -int ap_max_workers_limit = -1; -server_rec *ap_server_conf; - -/* *Non*-shared http_main globals... */ - -int hold_screen_on_exit = 0; /* Indicates whether the screen should be held open */ - -static fd_set listenfds; -static int listenmaxfd; - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pmain; /* Pool for httpd child stuff */ - -static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ -static char *ap_my_addrspace = NULL; - -static int die_now = 0; - -/* Keep track of the number of worker threads currently active */ -static unsigned long worker_thread_count; -static int request_count; - -/* Structure used to register/deregister a console handler with the OS */ -static int InstallConsoleHandler(void); -static void RemoveConsoleHandler(void); -static int CommandLineInterpreter(scr_t screenID, const char *commandLine); -static CommandParser_t ConsoleHandler = {0, NULL, 0}; -#define HANDLEDCOMMAND 0 -#define NOTMYCOMMAND 1 - -static int show_settings = 0; - -//#define DBINFO_ON -//#define DBPRINT_ON -#ifdef DBPRINT_ON -#define DBPRINT0(s) printf(s) -#define DBPRINT1(s,v1) printf(s,v1) -#define DBPRINT2(s,v1,v2) printf(s,v1,v2) -#else -#define DBPRINT0(s) -#define DBPRINT1(s,v1) -#define DBPRINT2(s,v1,v2) -#endif - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; -static int volatile wait_to_finish=1; -ap_generation_t volatile ap_my_generation=0; - -/* a clean exit from a child with proper cleanup */ -static void clean_child_exit(int code, int worker_num, apr_pool_t *ptrans, - apr_bucket_alloc_t *bucket_alloc) __attribute__ ((noreturn)); -static void clean_child_exit(int code, int worker_num, apr_pool_t *ptrans, - apr_bucket_alloc_t *bucket_alloc) -{ - apr_bucket_alloc_destroy(bucket_alloc); - if (!shutdown_pending) { - apr_pool_destroy(ptrans); - } - - atomic_dec (&worker_thread_count); - if (worker_num >=0) - ap_update_child_status_from_indexes(0, worker_num, WORKER_DEAD, - (request_rec *) NULL); - NXThreadExit((void*)&code); -} - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = 1; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = HARD_SERVER_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = HARD_THREAD_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = ap_threads_limit; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = ap_threads_min_free; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = ap_threads_max_free; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = 1; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - - -/***************************************************************** - * Connection structures and accounting... - */ - -static void mpm_term(void) -{ - RemoveConsoleHandler(); - wait_to_finish = 0; - NXThreadYield(); -} - -static void sig_term(int sig) -{ - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; - - DBPRINT0 ("waiting for threads\n"); - while (wait_to_finish) { - apr_thread_yield(); - } - DBPRINT0 ("goodbye\n"); -} - -/* restart() is the signal handler for SIGHUP and SIGWINCH - * in the parent process, unless running in ONE_PROCESS mode - */ -static void restart(void) -{ - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = 1; -} - -static void set_signals(void) -{ - apr_signal(SIGTERM, sig_term); - apr_signal(SIGABRT, sig_term); -} - -int nlmUnloadSignaled(int wait) -{ - shutdown_pending = 1; - - if (wait) { - while (wait_to_finish) { - NXThreadYield(); - } - } - - return 0; -} - -/***************************************************************** - * Child process main loop. - * The following vars are static to avoid getting clobbered by longjmp(); - * they are really private to child_main. - */ - - -int ap_graceful_stop_signalled(void) -{ - /* not ever called anymore... */ - return 0; -} - -#define MAX_WB_RETRIES 3 -#ifdef DBINFO_ON -static int would_block = 0; -static int retry_success = 0; -static int retry_fail = 0; -static int avg_retries = 0; -#endif - -/*static */ -void worker_main(void *arg) -{ - ap_listen_rec *lr, *first_lr, *last_lr = NULL; - apr_pool_t *ptrans; - apr_pool_t *pbucket; - apr_allocator_t *allocator; - apr_bucket_alloc_t *bucket_alloc; - conn_rec *current_conn; - apr_status_t stat = APR_EINIT; - ap_sb_handle_t *sbh; - - int my_worker_num = (int)arg; - apr_socket_t *csd = NULL; - int requests_this_child = 0; - apr_socket_t *sd = NULL; - fd_set main_fds; - - int sockdes; - int srv; - struct timeval tv; - int wouldblock_retry; - - tv.tv_sec = 1; - tv.tv_usec = 0; - - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - - apr_pool_create_ex(&ptrans, pmain, NULL, allocator); - apr_allocator_owner_set(allocator, ptrans); - apr_pool_tag(ptrans, "transaction"); - - bucket_alloc = apr_bucket_alloc_create_ex(allocator); - - atomic_inc (&worker_thread_count); - - while (!die_now) { - /* - * (Re)initialize this child to a pre-connection state. - */ - current_conn = NULL; - apr_pool_clear(ptrans); - - if ((ap_max_requests_per_child > 0 - && requests_this_child++ >= ap_max_requests_per_child)) { - DBPRINT1 ("\n**Thread slot %d is shutting down", my_worker_num); - clean_child_exit(0, my_worker_num, ptrans, bucket_alloc); - } - - ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY, - (request_rec *) NULL); - - /* - * Wait for an acceptable connection to arrive. - */ - - for (;;) { - if (shutdown_pending || restart_pending || (ap_scoreboard_image->servers[0][my_worker_num].status == WORKER_IDLE_KILL)) { - DBPRINT1 ("\nThread slot %d is shutting down\n", my_worker_num); - clean_child_exit(0, my_worker_num, ptrans, bucket_alloc); - } - - /* Check the listen queue on all sockets for requests */ - memcpy(&main_fds, &listenfds, sizeof(fd_set)); - srv = select(listenmaxfd + 1, &main_fds, NULL, NULL, &tv); - - if (srv <= 0) { - if (srv < 0) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, WSAGetLastError(), ap_server_conf, - "select() failed on listen socket"); - apr_thread_yield(); - } - continue; - } - - /* remember the last_lr we searched last time around so that - we don't end up starving any particular listening socket */ - if (last_lr == NULL) { - lr = ap_listeners; - } - else { - lr = last_lr->next; - if (!lr) - lr = ap_listeners; - } - first_lr = lr; - do { - apr_os_sock_get(&sockdes, lr->sd); - if (FD_ISSET(sockdes, &main_fds)) - goto got_listener; - lr = lr->next; - if (!lr) - lr = ap_listeners; - } while (lr != first_lr); - /* if we get here, something unexpected happened. Go back - into the select state and try again. - */ - continue; - got_listener: - last_lr = lr; - sd = lr->sd; - - wouldblock_retry = MAX_WB_RETRIES; - - while (wouldblock_retry) { - if ((stat = apr_accept(&csd, sd, ptrans)) == APR_SUCCESS) { - break; - } - else { - /* if the error is a wouldblock then maybe we were too - quick try to pull the next request from the listen - queue. Try a few more times then return to our idle - listen state. */ - if (!APR_STATUS_IS_EAGAIN(stat)) { - break; - } - - if (wouldblock_retry--) { - apr_thread_yield(); - } - } - } - - /* If we got a new socket, set it to non-blocking mode and process - it. Otherwise handle the error. */ - if (stat == APR_SUCCESS) { - apr_socket_opt_set(csd, APR_SO_NONBLOCK, 0); -#ifdef DBINFO_ON - if (wouldblock_retry < MAX_WB_RETRIES) { - retry_success++; - avg_retries += (MAX_WB_RETRIES-wouldblock_retry); - } -#endif - break; /* We have a socket ready for reading */ - } - else { -#ifdef DBINFO_ON - if (APR_STATUS_IS_EAGAIN(stat)) { - would_block++; - retry_fail++; - } - else -#else - if (APR_STATUS_IS_EAGAIN(stat) || -#endif - APR_STATUS_IS_ECONNRESET(stat) || - APR_STATUS_IS_ETIMEDOUT(stat) || - APR_STATUS_IS_EHOSTUNREACH(stat) || - APR_STATUS_IS_ENETUNREACH(stat)) { - ; - } - else if (APR_STATUS_IS_ENETDOWN(stat)) { - /* - * When the network layer has been shut down, there - * is not much use in simply exiting: the parent - * would simply re-create us (and we'd fail again). - * Use the CHILDFATAL code to tear the server down. - * @@@ Martin's idea for possible improvement: - * A different approach would be to define - * a new APEXIT_NETDOWN exit code, the reception - * of which would make the parent shutdown all - * children, then idle-loop until it detected that - * the network is up again, and restart the children. - * Ben Hyde noted that temporary ENETDOWN situations - * occur in mobile IP. - */ - ap_log_error(APLOG_MARK, APLOG_EMERG, stat, ap_server_conf, - "apr_accept: giving up."); - clean_child_exit(APEXIT_CHILDFATAL, my_worker_num, ptrans, - bucket_alloc); - } - else { - ap_log_error(APLOG_MARK, APLOG_ERR, stat, ap_server_conf, - "apr_accept: (client socket)"); - clean_child_exit(1, my_worker_num, ptrans, bucket_alloc); - } - } - } - - ap_create_sb_handle(&sbh, ptrans, 0, my_worker_num); - /* - * We now have a connection, so set it up with the appropriate - * socket options, file descriptors, and read/write buffers. - */ - current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, - my_worker_num, sbh, - bucket_alloc); - if (current_conn) { - ap_process_connection(current_conn, csd); - ap_lingering_close(current_conn); - } - request_count++; - } - clean_child_exit(0, my_worker_num, ptrans, bucket_alloc); -} - - -static int make_child(server_rec *s, int slot) -{ - int tid; - int err=0; - NXContext_t ctx; - - if (slot + 1 > ap_max_workers_limit) { - ap_max_workers_limit = slot + 1; - } - - ap_update_child_status_from_indexes(0, slot, WORKER_STARTING, - (request_rec *) NULL); - - if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stack_size, NX_CTX_NORMAL, &err)) { - char threadName[32]; - - sprintf (threadName, "Apache_Worker %d", slot); - NXContextSetName(ctx, threadName); - err = NXThreadCreate(ctx, NX_THR_BIND_CONTEXT, &tid); - if (err) { - NXContextFree (ctx); - } - } - - if (err) { - /* create thread didn't succeed. Fix the scoreboard or else - * it will say SERVER_STARTING forever and ever - */ - ap_update_child_status_from_indexes(0, slot, WORKER_DEAD, - (request_rec *) NULL); - - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again. */ - apr_thread_yield(); - - return -1; - } - - ap_scoreboard_image->servers[0][slot].tid = tid; - - return 0; -} - - -/* start up a bunch of worker threads */ -static void startup_workers(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < ap_threads_limit; ++i) { - if (ap_scoreboard_image->servers[0][i].status != WORKER_DEAD) { - continue; - } - if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; - } -} - - -/* - * idle_spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough idle servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int idle_spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (64) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_idle_server_maintenance(apr_pool_t *p) -{ - int i; - int to_kill; - int idle_count; - worker_score *ws; - int free_length; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead; - int total_non_dead; - - /* initialize the free_list */ - free_length = 0; - - to_kill = -1; - idle_count = 0; - last_non_dead = -1; - total_non_dead = 0; - - for (i = 0; i < ap_threads_limit; ++i) { - int status; - - if (i >= ap_max_workers_limit && free_length == idle_spawn_rate) - break; - ws = &ap_scoreboard_image->servers[0][i]; - status = ws->status; - if (status == WORKER_DEAD) { - /* try to keep children numbers as low as possible */ - if (free_length < idle_spawn_rate) { - free_slots[free_length] = i; - ++free_length; - } - } - else if (status == WORKER_IDLE_KILL) { - /* If it is already marked to die, skip it */ - continue; - } - else { - /* We consider a starting server as idle because we started it - * at least a cycle ago, and if it still hasn't finished starting - * then we're just going to swamp things worse by forking more. - * So we hopefully won't need to fork more if we count it. - * This depends on the ordering of SERVER_READY and SERVER_STARTING. - */ - if (status <= WORKER_READY) { - ++ idle_count; - /* always kill the highest numbered child if we have to... - * no really well thought out reason ... other than observing - * the server behaviour under linux where lower numbered children - * tend to service more hits (and hence are more likely to have - * their data in cpu caches). - */ - to_kill = i; - } - - ++total_non_dead; - last_non_dead = i; - } - } - DBPRINT2("Total: %d Idle Count: %d \r", total_non_dead, idle_count); - ap_max_workers_limit = last_non_dead + 1; - if (idle_count > ap_threads_max_free) { - /* kill off one child... we use the pod because that'll cause it to - * shut down gracefully, in case it happened to pick up a request - * while we were counting - */ - idle_spawn_rate = 1; - ap_update_child_status_from_indexes(0, last_non_dead, WORKER_IDLE_KILL, - (request_rec *) NULL); - DBPRINT1("\nKilling idle thread: %d\n", last_non_dead); - } - else if (idle_count < ap_threads_min_free) { - /* terminate the free list */ - if (free_length == 0) { - /* only report this condition once */ - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, - "server reached MaxClients setting, consider" - " raising the MaxClients setting"); - reported = 1; - } - idle_spawn_rate = 1; - } - else { - if (idle_spawn_rate >= 8) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "server seems busy, (you may need " - "to increase StartServers, or Min/MaxSpareServers), " - "spawning %d children, there are %d idle, and " - "%d total children", idle_spawn_rate, - idle_count, total_non_dead); - } - DBPRINT0("\n"); - for (i = 0; i < free_length; ++i) { - DBPRINT1("Spawning additional thread slot: %d\n", free_slots[i]); - make_child(ap_server_conf, free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } - else if (idle_spawn_rate < MAX_SPAWN_RATE) { - idle_spawn_rate *= 2; - } - } - } - else { - idle_spawn_rate = 1; - } -} - -static void display_settings () -{ - int status_array[SERVER_NUM_STATUS]; - int i, status, total=0; - int reqs = request_count; -#ifdef DBINFO_ON - int wblock = would_block; - - would_block = 0; -#endif - - request_count = 0; - - ClearScreen (getscreenhandle()); - printf("%s \n", ap_get_server_version()); - - for (i=0;i<SERVER_NUM_STATUS;i++) { - status_array[i] = 0; - } - - for (i = 0; i < ap_threads_limit; ++i) { - status = (ap_scoreboard_image->servers[0][i]).status; - status_array[status]++; - } - - for (i=0;i<SERVER_NUM_STATUS;i++) { - switch(i) - { - case SERVER_DEAD: - printf ("Available:\t%d\n", status_array[i]); - break; - case SERVER_STARTING: - printf ("Starting:\t%d\n", status_array[i]); - break; - case SERVER_READY: - printf ("Ready:\t\t%d\n", status_array[i]); - break; - case SERVER_BUSY_READ: - printf ("Busy:\t\t%d\n", status_array[i]); - break; - case SERVER_BUSY_WRITE: - printf ("Busy Write:\t%d\n", status_array[i]); - break; - case SERVER_BUSY_KEEPALIVE: - printf ("Busy Keepalive:\t%d\n", status_array[i]); - break; - case SERVER_BUSY_LOG: - printf ("Busy Log:\t%d\n", status_array[i]); - break; - case SERVER_BUSY_DNS: - printf ("Busy DNS:\t%d\n", status_array[i]); - break; - case SERVER_CLOSING: - printf ("Closing:\t%d\n", status_array[i]); - break; - case SERVER_GRACEFUL: - printf ("Restart:\t%d\n", status_array[i]); - break; - case SERVER_IDLE_KILL: - printf ("Idle Kill:\t%d\n", status_array[i]); - break; - default: - printf ("Unknown Status:\t%d\n", status_array[i]); - break; - } - if (i != SERVER_DEAD) - total+=status_array[i]; - } - printf ("Total Running:\t%d\tout of: \t%d\n", total, ap_threads_limit); - printf ("Requests per interval:\t%d\n", reqs); - -#ifdef DBINFO_ON - printf ("Would blocks:\t%d\n", wblock); - printf ("Successful retries:\t%d\n", retry_success); - printf ("Failed retries:\t%d\n", retry_fail); - printf ("Avg retries:\t%d\n", retry_success == 0 ? 0 : avg_retries / retry_success); -#endif -} - -static void show_server_data() -{ - ap_listen_rec *lr; - module **m; - - printf("%s\n", ap_get_server_version()); - if (ap_my_addrspace && (ap_my_addrspace[0] != 'O') && (ap_my_addrspace[1] != 'S')) - printf(" Running in address space %s\n", ap_my_addrspace); - - - /* Display listening ports */ - printf(" Listening on port(s):"); - lr = ap_listeners; - do { - printf(" %d", lr->bind_addr->port); - lr = lr->next; - } while(lr && lr != ap_listeners); - - /* Display dynamic modules loaded */ - printf("\n"); - for (m = ap_loaded_modules; *m != NULL; m++) { - if (((module*)*m)->dynamic_load_handle) { - printf(" Loaded dynamic module %s\n", ((module*)*m)->name); - } - } -} - - -static int setup_listeners(server_rec *s) -{ - ap_listen_rec *lr; - int sockdes; - - if (ap_setup_listeners(s) < 1 ) { - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, - "no listening sockets available, shutting down"); - return -1; - } - - listenmaxfd = -1; - FD_ZERO(&listenfds); - for (lr = ap_listeners; lr; lr = lr->next) { - apr_os_sock_get(&sockdes, lr->sd); - FD_SET(sockdes, &listenfds); - if (sockdes > listenmaxfd) { - listenmaxfd = sockdes; - } - } - return 0; -} - -static int shutdown_listeners() -{ - ap_listen_rec *lr; - - for (lr = ap_listeners; lr; lr = lr->next) { - apr_socket_close(lr->sd); - } - ap_listeners = NULL; - return 0; -} - -/***************************************************************** - * Executive routines. - */ - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - apr_status_t status=0; - - pconf = _pconf; - ap_server_conf = s; - - if (setup_listeners(s)) { - ap_log_error(APLOG_MARK, APLOG_ALERT, status, s, - "no listening sockets available, shutting down"); - return -1; - } - - restart_pending = shutdown_pending = 0; - worker_thread_count = 0; - - if (!is_graceful) { - if (ap_run_pre_mpm(s->process->pool, SB_NOT_SHARED) != OK) { - return 1; - } - } - - /* Only set slot 0 since that is all NetWare will ever have. */ - ap_scoreboard_image->parent[0].pid = getpid(); - - set_signals(); - - apr_pool_create(&pmain, pconf); - ap_run_child_init(pmain, ap_server_conf); - - if (ap_threads_max_free < ap_threads_min_free + 1) /* Don't thrash... */ - ap_threads_max_free = ap_threads_min_free + 1; - request_count = 0; - - startup_workers(ap_threads_to_start); - - /* Allow the Apache screen to be closed normally on exit() only if it - has not been explicitly forced to close on exit(). (ie. the -E flag - was specified at startup) */ - if (hold_screen_on_exit > 0) { - hold_screen_on_exit = 0; - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(accept_mutex), - apr_proc_mutex_defname()); -#endif - show_server_data(); - - mpm_state = AP_MPMQ_RUNNING; - while (!restart_pending && !shutdown_pending) { - perform_idle_server_maintenance(pconf); - if (show_settings) - display_settings(); - apr_thread_yield(); - apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); - } - mpm_state = AP_MPMQ_STOPPING; - - - /* Shutdown the listen sockets so that we don't get stuck in a blocking call. - shutdown_listeners();*/ - - if (shutdown_pending) { /* Got an unload from the console */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "caught SIGTERM, shutting down"); - - while (worker_thread_count > 0) { - printf ("\rShutdown pending. Waiting for %d thread(s) to terminate...", - worker_thread_count); - apr_thread_yield(); - } - - return 1; - } - else { /* the only other way out is a restart */ - /* advance to the next generation */ - /* XXX: we really need to make sure this new generation number isn't in - * use by any of the children. - */ - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "Graceful restart requested, doing restart"); - - /* Wait for all of the threads to terminate before initiating the restart */ - while (worker_thread_count > 0) { - printf ("\rRestart pending. Waiting for %d thread(s) to terminate...", - worker_thread_count); - apr_thread_yield(); - } - printf ("\nRestarting...\n"); - } - - return 0; -} - -static int netware_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) -{ - int debug; - char *addrname = NULL; - - mpm_state = AP_MPMQ_STARTING; - - debug = ap_exists_config_define("DEBUG"); - - is_graceful = 0; - ap_my_pid = getpid(); - addrname = getaddressspacename (NULL, NULL); - if (addrname) { - ap_my_addrspace = apr_pstrdup (p, addrname); - free (addrname); - } - - ap_listen_pre_config(); - ap_threads_to_start = DEFAULT_START_THREADS; - ap_threads_min_free = DEFAULT_MIN_FREE_THREADS; - ap_threads_max_free = DEFAULT_MAX_FREE_THREADS; - ap_threads_limit = HARD_THREAD_LIMIT; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - return OK; -} - -static void netware_mpm_hooks(apr_pool_t *p) -{ - ap_hook_pre_config(netware_pre_config, NULL, NULL, APR_HOOK_MIDDLE); -} - -void netware_rewrite_args(process_rec *process) -{ - char *def_server_root; - char optbuf[3]; - const char *opt_arg; - apr_getopt_t *opt; - apr_array_header_t *mpm_new_argv; - - - atexit (mpm_term); - InstallConsoleHandler(); - - /* Make sure to hold the Apache screen open if exit() is called */ - hold_screen_on_exit = 1; - - /* Rewrite process->argv[]; - * - * add default -d serverroot from the path of this executable - * - * The end result will look like: - * The -d serverroot default from the running executable - */ - if (process->argc > 0) { - char *s = apr_pstrdup (process->pconf, process->argv[0]); - if (s) { - int i, len = strlen(s); - - for (i=len; i; i--) { - if (s[i] == '\\' || s[i] == '/') { - s[i] = '\0'; - apr_filepath_merge(&def_server_root, NULL, s, - APR_FILEPATH_TRUENAME, process->pool); - break; - } - } - /* Use process->pool so that the rewritten argv - * lasts for the lifetime of the server process, - * because pconf will be destroyed after the - * initial pre-flight of the config parser. - */ - mpm_new_argv = apr_array_make(process->pool, process->argc + 2, - sizeof(const char *)); - *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; - *(const char **)apr_array_push(mpm_new_argv) = "-d"; - *(const char **)apr_array_push(mpm_new_argv) = def_server_root; - - optbuf[0] = '-'; - optbuf[2] = '\0'; - apr_getopt_init(&opt, process->pool, process->argc, (char**) process->argv); - while (apr_getopt(opt, AP_SERVER_BASEARGS"n:", optbuf + 1, &opt_arg) == APR_SUCCESS) { - switch (optbuf[1]) { - case 'n': - if (opt_arg) { - renamescreen(opt_arg); - } - break; - case 'E': - /* Don't need to hold the screen open if the output is going to a file */ - hold_screen_on_exit = -1; - default: - *(const char **)apr_array_push(mpm_new_argv) = - apr_pstrdup(process->pool, optbuf); - - if (opt_arg) { - *(const char **)apr_array_push(mpm_new_argv) = opt_arg; - } - break; - } - } - process->argc = mpm_new_argv->nelts; - process->argv = (const char * const *) mpm_new_argv->elts; - } - } -} - -static int CommandLineInterpreter(scr_t screenID, const char *commandLine) -{ - char *szCommand = "APACHE2 "; - int iCommandLen = 8; - char szcommandLine[256]; - char *pID; - screenID = screenID; - - - if (commandLine == NULL) - return NOTMYCOMMAND; - if (strlen(commandLine) <= strlen(szCommand)) - return NOTMYCOMMAND; - - strncpy (szcommandLine, commandLine, sizeof(szcommandLine)-1); - - /* All added commands begin with "APACHE2 " */ - - if (!strnicmp(szCommand, szcommandLine, iCommandLen)) { - ActivateScreen (getscreenhandle()); - - /* If an instance id was not given but the nlm is loaded in - protected space, then the the command belongs to the - OS address space instance to pass it on. */ - pID = strstr (szcommandLine, "-p"); - if ((pID == NULL) && nlmisloadedprotected()) - return NOTMYCOMMAND; - - /* If we got an instance id but it doesn't match this - instance of the nlm, pass it on. */ - if (pID) { - pID = &pID[2]; - while (*pID && (*pID == ' ')) - pID++; - } - if (pID && ap_my_addrspace && strnicmp(pID, ap_my_addrspace, strlen(ap_my_addrspace))) - return NOTMYCOMMAND; - - /* If we have determined that this command belongs to this - instance of the nlm, then handle it. */ - if (!strnicmp("RESTART",&szcommandLine[iCommandLen],3)) { - printf("Restart Requested...\n"); - restart(); - } - else if (!strnicmp("VERSION",&szcommandLine[iCommandLen],3)) { - printf("Server version: %s\n", ap_get_server_version()); - printf("Server built: %s\n", ap_get_server_built()); - } - else if (!strnicmp("MODULES",&szcommandLine[iCommandLen],3)) { - ap_show_modules(); - } - else if (!strnicmp("DIRECTIVES",&szcommandLine[iCommandLen],3)) { - ap_show_directives(); - } - else if (!strnicmp("SHUTDOWN",&szcommandLine[iCommandLen],3)) { - printf("Shutdown Requested...\n"); - shutdown_pending = 1; - } - else if (!strnicmp("SETTINGS",&szcommandLine[iCommandLen],3)) { - if (show_settings) { - show_settings = 0; - ClearScreen (getscreenhandle()); - show_server_data(); - } - else { - show_settings = 1; - display_settings(); - } - } - else { - show_settings = 0; - if (strnicmp("HELP",&szcommandLine[iCommandLen],3)) - printf("Unknown APACHE2 command %s\n", &szcommandLine[iCommandLen]); - printf("Usage: APACHE2 [command] [-p <instance ID>]\n"); - printf("Commands:\n"); - printf("\tDIRECTIVES - Show directives\n"); - printf("\tHELP - Display this help information\n"); - printf("\tMODULES - Show a list of the loaded modules\n"); - printf("\tRESTART - Reread the configuration file and restart Apache\n"); - printf("\tSETTINGS - Show current thread status\n"); - printf("\tSHUTDOWN - Shutdown Apache\n"); - printf("\tVERSION - Display the server version information\n"); - } - - /* Tell NetWare we handled the command */ - return HANDLEDCOMMAND; - } - - /* Tell NetWare that the command isn't mine */ - return NOTMYCOMMAND; -} - -static int InstallConsoleHandler(void) -{ - /* Our command line handler interfaces the system operator - with this NLM */ - - NX_WRAP_INTERFACE(CommandLineInterpreter, 2, (void*)&(ConsoleHandler.parser)); - - ConsoleHandler.rTag = AllocateResourceTag(getnlmhandle(), "Command Line Processor", - ConsoleCommandSignature); - if (!ConsoleHandler.rTag) - { - printf("Error on allocate resource tag\n"); - return 1; - } - - RegisterConsoleCommand(&ConsoleHandler); - - /* The Remove procedure unregisters the console handler */ - - return 0; -} - -static void RemoveConsoleHandler(void) -{ - UnRegisterConsoleCommand(&ConsoleHandler); - NX_UNWRAP_INTERFACE(ConsoleHandler.parser); -} - -static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_to_start = atoi(arg); - return NULL; -} - -static const char *set_min_free_threads(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_min_free = atoi(arg); - if (ap_threads_min_free <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareServers set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - ap_threads_min_free = 1; - } - - return NULL; -} - -static const char *set_max_free_threads(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_max_free = atoi(arg); - return NULL; -} - -static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_limit = atoi(arg); - if (ap_threads_limit > HARD_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxThreads of %d exceeds compile time limit " - "of %d threads,", ap_threads_limit, HARD_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering MaxThreads to %d. To increase, please " - "see the", HARD_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " HARD_THREAD_LIMIT define in %s.", - AP_MPM_HARD_LIMITS_FILE); - ap_threads_limit = HARD_THREAD_LIMIT; - } - else if (ap_threads_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require MaxThreads > 0, setting to 1"); - ap_threads_limit = 1; - } - return NULL; -} - -static const char *set_thread_stacksize(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_thread_stack_size = atoi(arg); - return NULL; -} - -static const command_rec netware_mpm_cmds[] = { -AP_INIT_TAKE1("ThreadStackSize", set_thread_stacksize, NULL, RSRC_CONF, - "Stack size each created thread will use."), -LISTEN_COMMANDS, -AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF, - "Number of worker threads launched at server startup"), -AP_INIT_TAKE1("MinSpareThreads", set_min_free_threads, NULL, RSRC_CONF, - "Minimum number of idle threads, to handle request spikes"), -AP_INIT_TAKE1("MaxSpareThreads", set_max_free_threads, NULL, RSRC_CONF, - "Maximum number of idle threads"), -AP_INIT_TAKE1("MaxThreads", set_thread_limit, NULL, RSRC_CONF, - "Maximum number of worker threads alive at the same time"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_netware_module = { - MPM20_MODULE_STUFF, - netware_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - netware_mpm_cmds, /* command apr_table_t */ - netware_mpm_hooks, /* register hooks */ -}; diff --git a/rubbos/app/httpd-2.0.64/server/mpm/prefork/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/prefork/Makefile.in deleted file mode 100644 index 034bf5ce..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/prefork/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libprefork.la -LTLIBRARY_SOURCES = prefork.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/prefork/config.m4 b/rubbos/app/httpd-2.0.64/server/mpm/prefork/config.m4 deleted file mode 100644 index 9c189a86..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/prefork/config.m4 +++ /dev/null @@ -1,3 +0,0 @@ -if test "$MPM_NAME" = "prefork" ; then - APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/prefork/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/prefork/mpm.h deleted file mode 100644 index 51f810b3..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/prefork/mpm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "httpd.h" -#include "mpm_default.h" -#include "scoreboard.h" -#include "unixd.h" - -#ifndef APACHE_MPM_PREFORK_H -#define APACHE_MPM_PREFORK_H - -#define PREFORK_MPM - -#define MPM_NAME "Prefork" - -#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -#define AP_MPM_WANT_WAIT_OR_TIMEOUT -#define AP_MPM_WANT_PROCESS_CHILD_STATUS -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_LOCKFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -#define AP_MPM_WANT_SIGNAL_SERVER -#define AP_MPM_WANT_SET_MAX_MEM_FREE -#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER -#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK - -#define AP_MPM_USES_POD 1 -#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) -#define MPM_ACCEPT_FUNC unixd_accept - -extern int ap_threads_per_child; -extern int ap_max_daemons_limit; -extern server_rec *ap_server_conf; -#endif /* APACHE_MPM_PREFORK_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/prefork/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/prefork/mpm_default.h deleted file mode 100644 index 8ddf38f0..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/prefork/mpm_default.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of servers to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_DAEMON -#define DEFAULT_START_DAEMON 5 -#endif - -/* Maximum number of *free* server processes --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_FREE_DAEMON -#define DEFAULT_MAX_FREE_DAEMON 10 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_FREE_DAEMON -#define DEFAULT_MIN_FREE_DAEMON 5 -#endif - -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/prefork/prefork.c b/rubbos/app/httpd-2.0.64/server/mpm/prefork/prefork.c deleted file mode 100644 index 8667b4ab..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/prefork/prefork.c +++ /dev/null @@ -1,1355 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_portable.h" -#include "apr_strings.h" -#include "apr_thread_proc.h" -#include "apr_signal.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "mpm_default.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "scoreboard.h" -#include "ap_mpm.h" -#include "unixd.h" -#include "mpm_common.h" -#include "ap_listen.h" -#include "ap_mmn.h" -#include "apr_poll.h" - -#ifdef HAVE_BSTRING_H -#include <bstring.h> /* for IRIX, FD_SET calls bzero() */ -#endif -#ifdef HAVE_TIME_H -#include <time.h> -#endif -#ifdef HAVE_SYS_PROCESSOR_H -#include <sys/processor.h> /* for bindprocessor() */ -#endif - -#include <signal.h> -#include <sys/times.h> - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_SERVER_LIMIT -#define DEFAULT_SERVER_LIMIT 256 -#endif - -/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_SERVER_LIMIT -#define MAX_SERVER_LIMIT 20000 -#endif - -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 1 -#endif - -/* config globals */ - -int ap_threads_per_child=0; /* Worker threads per child */ -static apr_proc_mutex_t *accept_mutex; -static int ap_daemons_to_start=0; -static int ap_daemons_min_free=0; -static int ap_daemons_max_free=0; -static int ap_daemons_limit=0; /* MaxClients */ -static int server_limit = DEFAULT_SERVER_LIMIT; -static int first_server_limit; -static int changed_limit_at_restart; -static int mpm_state = AP_MPMQ_STARTING; -static ap_pod_t *pod; - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We - * use this value to optimize routines that have to scan the entire scoreboard. - */ -int ap_max_daemons_limit = -1; -server_rec *ap_server_conf; - -/* one_process --- debugging mode variable; can be set from the command line - * with the -X flag. If set, this gets you the child_main loop running - * in the process which originally started up (no detach, no make_child), - * which is a pretty nice debugging environment. (You'll get a SIGHUP - * early in standalone_main; just continue through. This is the server - * trying to kill off any child processes which it might have lying - * around --- Apache doesn't keep track of their pids, it just sends - * SIGHUP to the process group, ignoring it in the root process. - * Continue through and you'll be fine.). - */ - -static int one_process = 0; - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pchild; /* Pool for httpd child stuff */ - -static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ -static pid_t parent_pid; -#ifndef MULTITHREAD -static int my_child_num; -#endif -ap_generation_t volatile ap_my_generation=0; - -#ifdef TPF -int tpf_child = 0; -char tpf_server_name[INETD_SERVNAME_LENGTH+1]; -#endif /* TPF */ - -static int die_now = 0; - -#ifdef GPROF -/* - * change directory for gprof to plop the gmon.out file - * configure in httpd.conf: - * GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out - * GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out - */ -static void chdir_for_gprof(void) -{ - core_server_config *sconf = - ap_get_module_config(ap_server_conf->module_config, &core_module); - char *dir = sconf->gprof_dir; - const char *use_dir; - - if(dir) { - apr_status_t res; - char buf[512]; - int len = strlen(sconf->gprof_dir) - 1; - if(*(dir + len) == '%') { - dir[len] = '\0'; - apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid()); - } - use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir); - res = apr_dir_make(use_dir, 0755, pconf); - if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf, - "gprof: error creating directory %s", dir); - } - } - else { - use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR); - } - - chdir(use_dir); -} -#else -#define chdir_for_gprof() -#endif - -/* XXX - I don't know if TPF will ever use this module or not, so leave - * the ap_check_signals calls in but disable them - manoj */ -#define ap_check_signals() - -/* a clean exit from a child with proper cleanup */ -static void clean_child_exit(int code) __attribute__ ((noreturn)); -static void clean_child_exit(int code) -{ - mpm_state = AP_MPMQ_STOPPING; - - if (pchild) { - apr_pool_destroy(pchild); - } - ap_mpm_pod_close(pod); - chdir_for_gprof(); - exit(code); -} - -static void accept_mutex_on(void) -{ - apr_status_t rv = apr_proc_mutex_lock(accept_mutex); - if (rv != APR_SUCCESS) { - const char *msg = "couldn't grab the accept mutex"; - - if (ap_my_generation != - ap_scoreboard_image->global->running_generation) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg); - clean_child_exit(0); - } - else { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, msg); - exit(APEXIT_CHILDFATAL); - } - } -} - -static void accept_mutex_off(void) -{ - apr_status_t rv = apr_proc_mutex_unlock(accept_mutex); - if (rv != APR_SUCCESS) { - const char *msg = "couldn't release the accept mutex"; - - if (ap_my_generation != - ap_scoreboard_image->global->running_generation) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg); - /* don't exit here... we have a connection to - * process, after which point we'll see that the - * generation changed and we'll exit cleanly - */ - } - else { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, msg); - exit(APEXIT_CHILDFATAL); - } - } -} - -/* On some architectures it's safe to do unserialized accept()s in the single - * Listen case. But it's never safe to do it in the case where there's - * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT - * when it's safe in the single Listen case. - */ -#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT -#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0) -#else -#define SAFE_ACCEPT(stmt) do {stmt;} while(0) -#endif - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = server_limit; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = HARD_THREAD_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = ap_daemons_min_free; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = ap_daemons_max_free; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = server_limit; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -#if defined(NEED_WAITPID) -/* - Systems without a real waitpid sometimes lose a child's exit while waiting - for another. Search through the scoreboard for missing children. - */ -int reap_children(int *exitcode, apr_exit_why_e *status) -{ - int n, pid; - - for (n = 0; n < ap_max_daemons_limit; ++n) { - if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && - kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { - ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); - /* just mark it as having a successful exit status */ - *status = APR_PROC_EXIT; - *exitcode = 0; - return(pid); - } - } - return 0; -} -#endif - -/***************************************************************** - * Connection structures and accounting... - */ - -static void just_die(int sig) -{ - clean_child_exit(0); -} - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; - -static void sig_term(int sig) -{ - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; -} - -/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL - * in the parent process, unless running in ONE_PROCESS mode - */ -static void restart(int sig) -{ - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = (sig == AP_SIG_GRACEFUL); -} - -static void set_signals(void) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; -#endif - - if (!one_process) { - ap_fatal_signal_setup(ap_server_conf, pconf); - } - -#ifndef NO_USE_SIGACTION - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); -#ifdef SIGINT - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); -#endif -#ifdef SIGXCPU - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXCPU, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)"); -#endif -#ifdef SIGXFSZ - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXFSZ, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)"); -#endif -#ifdef SIGPIPE - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)"); -#endif - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -#else - if (!one_process) { -#ifdef SIGXCPU - apr_signal(SIGXCPU, SIG_DFL); -#endif /* SIGXCPU */ -#ifdef SIGXFSZ - apr_signal(SIGXFSZ, SIG_DFL); -#endif /* SIGXFSZ */ - } - - apr_signal(SIGTERM, sig_term); -#ifdef SIGHUP - apr_signal(SIGHUP, restart); -#endif /* SIGHUP */ -#ifdef AP_SIG_GRACEFUL - apr_signal(AP_SIG_GRACEFUL, restart); -#endif /* AP_SIG_GRACEFUL */ -#ifdef SIGPIPE - apr_signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - -#endif -} - -/***************************************************************** - * Child process main loop. - * The following vars are static to avoid getting clobbered by longjmp(); - * they are really private to child_main. - */ - -static int requests_this_child; -static int num_listensocks = 0; -static ap_listen_rec *listensocks; - -int ap_graceful_stop_signalled(void) -{ - /* not ever called anymore... */ - return 0; -} - - -static void child_main(int child_num_arg) -{ - apr_pool_t *ptrans; - apr_allocator_t *allocator; - conn_rec *current_conn; - apr_status_t status = APR_EINIT; - int i; - ap_listen_rec *lr; - int curr_pollfd, last_pollfd = 0; - apr_pollfd_t *pollset; - int offset; - void *csd; - ap_sb_handle_t *sbh; - apr_status_t rv; - apr_bucket_alloc_t *bucket_alloc; - - mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this - * child initializes - */ - - my_child_num = child_num_arg; - ap_my_pid = getpid(); - csd = NULL; - requests_this_child = 0; - - ap_fatal_signal_child_setup(ap_server_conf); - - /* Get a sub context for global allocations in this child, so that - * we can have cleanups occur when the child exits. - */ - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - apr_pool_create_ex(&pchild, pconf, NULL, allocator); - apr_allocator_owner_set(allocator, pchild); - - apr_pool_create(&ptrans, pchild); - apr_pool_tag(ptrans, "transaction"); - - /* needs to be done before we switch UIDs so we have permissions */ - ap_reopen_scoreboard(pchild, NULL, 0); - rv = apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize cross-process lock in child"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (unixd_setup_child()) { - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_run_child_init(pchild, ap_server_conf); - - ap_create_sb_handle(&sbh, pchild, my_child_num, 0); - - (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); - - /* Set up the pollfd array */ - listensocks = apr_pcalloc(pchild, - sizeof(*listensocks) * (num_listensocks)); - for (lr = ap_listeners, i = 0; i < num_listensocks; lr = lr->next, i++) { - listensocks[i].accept_func = lr->accept_func; - listensocks[i].sd = lr->sd; - } - - pollset = apr_palloc(pchild, sizeof(*pollset) * num_listensocks); - pollset[0].p = pchild; - for (i = 0; i < num_listensocks; i++) { - pollset[i].desc.s = listensocks[i].sd; - pollset[i].desc_type = APR_POLL_SOCKET; - pollset[i].reqevents = APR_POLLIN; - } - - mpm_state = AP_MPMQ_RUNNING; - - bucket_alloc = apr_bucket_alloc_create(pchild); - - while (!die_now) { - /* - * (Re)initialize this child to a pre-connection state. - */ - - current_conn = NULL; - - apr_pool_clear(ptrans); - - if ((ap_max_requests_per_child > 0 - && requests_this_child++ >= ap_max_requests_per_child)) { - clean_child_exit(0); - } - - (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); - - /* - * Wait for an acceptable connection to arrive. - */ - - /* Lock around "accept", if necessary */ - SAFE_ACCEPT(accept_mutex_on()); - - if (num_listensocks == 1) { - offset = 0; - } - else { - /* multiple listening sockets - need to poll */ - for (;;) { - apr_status_t ret; - apr_int32_t n; - - ret = apr_poll(pollset, num_listensocks, &n, -1); - if (ret != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(ret)) { - continue; - } - /* Single Unix documents select as returning errnos - * EBADF, EINTR, and EINVAL... and in none of those - * cases does it make sense to continue. In fact - * on Linux 2.0.x we seem to end up with EFAULT - * occasionally, and we'd loop forever due to it. - */ - ap_log_error(APLOG_MARK, APLOG_ERR, ret, ap_server_conf, - "apr_poll: (listen)"); - clean_child_exit(1); - } - /* find a listener */ - curr_pollfd = last_pollfd; - do { - curr_pollfd++; - if (curr_pollfd >= num_listensocks) { - curr_pollfd = 0; - } - /* XXX: Should we check for POLLERR? */ - if (pollset[curr_pollfd].rtnevents & APR_POLLIN) { - last_pollfd = curr_pollfd; - offset = curr_pollfd; - goto got_fd; - } - } while (curr_pollfd != last_pollfd); - - continue; - } - } - got_fd: - /* if we accept() something we don't want to die, so we have to - * defer the exit - */ - status = listensocks[offset].accept_func(&csd, - &listensocks[offset], ptrans); - SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ - - if (status == APR_EGENERAL) { - /* resource shortage or should-not-occur occured */ - clean_child_exit(1); - } - else if (status != APR_SUCCESS) { - continue; - } - - /* - * We now have a connection, so set it up with the appropriate - * socket options, file descriptors, and read/write buffers. - */ - - current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc); - if (current_conn) { - ap_process_connection(current_conn, csd); - ap_lingering_close(current_conn); - } - - /* Check the pod and the generation number after processing a - * connection so that we'll go away if a graceful restart occurred - * while we were processing the connection or we are the lucky - * idle server process that gets to die. - */ - if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */ - die_now = 1; - } - else if (ap_my_generation != - ap_scoreboard_image->global->running_generation) { /* restart? */ - /* yeah, this could be non-graceful restart, in which case the - * parent will kill us soon enough, but why bother checking? - */ - die_now = 1; - } - } - clean_child_exit(0); -} - - -static int make_child(server_rec *s, int slot) -{ - int pid; - - if (slot + 1 > ap_max_daemons_limit) { - ap_max_daemons_limit = slot + 1; - } - - if (one_process) { - apr_signal(SIGHUP, just_die); - /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */ - apr_signal(SIGINT, just_die); -#ifdef SIGQUIT - apr_signal(SIGQUIT, SIG_DFL); -#endif - apr_signal(SIGTERM, just_die); - child_main(slot); - } - - (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, - (request_rec *) NULL); - - -#ifdef _OSD_POSIX - /* BS2000 requires a "special" version of fork() before a setuid() call */ - if ((pid = os_fork(unixd_config.user_name)) == -1) { -#elif defined(TPF) - if ((pid = os_fork(s, slot)) == -1) { -#else - if ((pid = fork()) == -1) { -#endif - ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process"); - - /* fork didn't succeed. Fix the scoreboard or else - * it will say SERVER_STARTING forever and ever - */ - (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, - (request_rec *) NULL); - - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again. */ - sleep(10); - - return -1; - } - - if (!pid) { -#ifdef HAVE_BINDPROCESSOR - /* by default AIX binds to a single processor - * this bit unbinds children which will then bind to another cpu - */ - int status = bindprocessor(BINDPROCESS, (int)getpid(), - PROCESSOR_CLASS_ANY); - if (status != OK) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, - ap_server_conf, "processor unbind failed %d", status); - } -#endif - RAISE_SIGSTOP(MAKE_CHILD); - AP_MONCONTROL(1); - /* Disable the parent's signal handlers and set up proper handling in - * the child. - */ - apr_signal(SIGHUP, just_die); - apr_signal(SIGTERM, just_die); - /* The child process doesn't do anything for AP_SIG_GRACEFUL. - * Instead, the pod is used for signalling graceful restart. - */ - apr_signal(AP_SIG_GRACEFUL, SIG_IGN); - child_main(slot); - } - - ap_scoreboard_image->parent[slot].pid = pid; - - return 0; -} - - -/* start up a bunch of children */ -static void startup_children(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { - continue; - } - if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; - } -} - - -/* - * idle_spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough idle servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int idle_spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (32) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_idle_server_maintenance(apr_pool_t *p) -{ - int i; - int to_kill; - int idle_count; - worker_score *ws; - int free_length; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead; - int total_non_dead; - - /* initialize the free_list */ - free_length = 0; - - to_kill = -1; - idle_count = 0; - last_non_dead = -1; - total_non_dead = 0; - - for (i = 0; i < ap_daemons_limit; ++i) { - int status; - - if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate) - break; - ws = &ap_scoreboard_image->servers[i][0]; - status = ws->status; - if (status == SERVER_DEAD) { - /* try to keep children numbers as low as possible */ - if (free_length < idle_spawn_rate) { - free_slots[free_length] = i; - ++free_length; - } - } - else { - /* We consider a starting server as idle because we started it - * at least a cycle ago, and if it still hasn't finished starting - * then we're just going to swamp things worse by forking more. - * So we hopefully won't need to fork more if we count it. - * This depends on the ordering of SERVER_READY and SERVER_STARTING. - */ - if (status <= SERVER_READY) { - ++ idle_count; - /* always kill the highest numbered child if we have to... - * no really well thought out reason ... other than observing - * the server behaviour under linux where lower numbered children - * tend to service more hits (and hence are more likely to have - * their data in cpu caches). - */ - to_kill = i; - } - - ++total_non_dead; - last_non_dead = i; - } - } - ap_max_daemons_limit = last_non_dead + 1; - if (idle_count > ap_daemons_max_free) { - /* kill off one child... we use the pod because that'll cause it to - * shut down gracefully, in case it happened to pick up a request - * while we were counting - */ - ap_mpm_pod_signal(pod); - idle_spawn_rate = 1; - } - else if (idle_count < ap_daemons_min_free) { - /* terminate the free list */ - if (free_length == 0) { - /* only report this condition once */ - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, - "server reached MaxClients setting, consider" - " raising the MaxClients setting"); - reported = 1; - } - idle_spawn_rate = 1; - } - else { - if (idle_spawn_rate >= 8) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "server seems busy, (you may need " - "to increase StartServers, or Min/MaxSpareServers), " - "spawning %d children, there are %d idle, and " - "%d total children", idle_spawn_rate, - idle_count, total_non_dead); - } - for (i = 0; i < free_length; ++i) { -#ifdef TPF - if (make_child(ap_server_conf, free_slots[i]) == -1) { - if(free_length == 1) { - shutdown_pending = 1; - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, ap_server_conf, - "No active child processes: shutting down"); - } - } -#else - make_child(ap_server_conf, free_slots[i]); -#endif /* TPF */ - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } - else if (idle_spawn_rate < MAX_SPAWN_RATE) { - idle_spawn_rate *= 2; - } - } - } - else { - idle_spawn_rate = 1; - } -} - -/***************************************************************** - * Executive routines. - */ - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - int index; - int remaining_children_to_start; - apr_status_t rv; - - ap_log_pid(pconf, ap_pid_fname); - - first_server_limit = server_limit; - if (changed_limit_at_restart) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "WARNING: Attempt to change ServerLimit " - "ignored during restart"); - changed_limit_at_restart = 0; - } - - /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, - ap_server_root_relative(_pconf, ap_lock_fname), - ap_my_pid); - - rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, - ap_accept_lock_mech, _pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - -#if APR_USE_SYSVSEM_SERIALIZE - if (ap_accept_lock_mech == APR_LOCK_DEFAULT || - ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#else - if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#endif - rv = unixd_set_proc_mutex_perms(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't set permissions on cross-process lock; " - "check User and Group directives"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - } - - if (!is_graceful) { - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - /* fix the generation number in the global score; we just got a new, - * cleared scoreboard - */ - ap_scoreboard_image->global->running_generation = ap_my_generation; - } - - set_signals(); - - if (one_process) { - AP_MONCONTROL(1); - } - - if (ap_daemons_max_free < ap_daemons_min_free + 1) /* Don't thrash... */ - ap_daemons_max_free = ap_daemons_min_free + 1; - - /* If we're doing a graceful_restart then we're going to see a lot - * of children exiting immediately when we get into the main loop - * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty - * rapidly... and for each one that exits we'll start a new one until - * we reach at least daemons_min_free. But we may be permitted to - * start more than that, so we'll just keep track of how many we're - * supposed to start up without the 1 second penalty between each fork. - */ - remaining_children_to_start = ap_daemons_to_start; - if (remaining_children_to_start > ap_daemons_limit) { - remaining_children_to_start = ap_daemons_limit; - } - if (!is_graceful) { - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - } - else { - /* give the system some time to recover before kicking into - * exponential mode */ - hold_off_on_exponential_spawning = 10; - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(accept_mutex), - apr_proc_mutex_defname()); -#endif - restart_pending = shutdown_pending = 0; - - mpm_state = AP_MPMQ_RUNNING; - - while (!restart_pending && !shutdown_pending) { - int child_slot; - apr_exit_why_e exitwhy; - int status, processed_status; - /* this is a memory leak, but I'll fix it later. */ - apr_proc_t pid; - - ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); - - /* XXX: if it takes longer than 1 second for all our children - * to start up and get into IDLE state then we may spawn an - * extra child - */ - if (pid.pid != -1) { - processed_status = ap_process_child_status(&pid, exitwhy, status); - if (processed_status == APEXIT_CHILDFATAL) { - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - - /* non-fatal death... note that it's gone in the scoreboard. */ - child_slot = find_child_by_pid(&pid); - if (child_slot >= 0) { - (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD, - (request_rec *) NULL); - if (processed_status == APEXIT_CHILDSICK) { - /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc) - * cut the fork rate to the minimum - */ - idle_spawn_rate = 1; - } - else if (remaining_children_to_start - && child_slot < ap_daemons_limit) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - make_child(ap_server_conf, child_slot); - --remaining_children_to_start; - } -#if APR_HAS_OTHER_CHILD - } - else if (apr_proc_other_child_read(&pid, status) == 0) { - /* handled */ -#endif - } - else if (is_graceful) { - /* Great, we've probably just lost a slot in the - * scoreboard. Somehow we don't know about this - * child. - */ - ap_log_error(APLOG_MARK, APLOG_WARNING, - 0, ap_server_conf, - "long lost child came home! (pid %ld)", (long)pid.pid); - } - /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ - continue; - } - else if (remaining_children_to_start) { - /* we hit a 1 second timeout in which none of the previous - * generation of children needed to be reaped... so assume - * they're all done, and pick up the slack if any is left. - */ - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - /* In any event we really shouldn't do the code below because - * few of the servers we just started are in the IDLE state - * yet, so we'd mistakenly create an extra server. - */ - continue; - } - - perform_idle_server_maintenance(pconf); -#ifdef TPF - shutdown_pending = os_check_server(tpf_server_name); - ap_check_signals(); - sleep(1); -#endif /*TPF */ - } - - mpm_state = AP_MPMQ_STOPPING; - - if (shutdown_pending) { - /* Time to gracefully shut down: - * Kill child processes, tell them to call child_exit, etc... - */ - if (unixd_killpg(getpgrp(), SIGTERM) < 0) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM"); - } - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - - /* cleanup pid file on normal shutdown */ - { - const char *pidfile = NULL; - pidfile = ap_server_root_relative (pconf, ap_pid_fname); - if ( pidfile != NULL && unlink(pidfile) == 0) - ap_log_error(APLOG_MARK, APLOG_INFO, - 0, ap_server_conf, - "removed PID file %s (pid=%ld)", - pidfile, (long)getpid()); - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "caught SIGTERM, shutting down"); - return 1; - } - - /* we've been told to restart */ - apr_signal(SIGHUP, SIG_IGN); - if (one_process) { - /* not worth thinking about */ - return 1; - } - - /* advance to the next generation */ - /* XXX: we really need to make sure this new generation number isn't in - * use by any of the children. - */ - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - - if (is_graceful) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "Graceful restart requested, doing restart"); - - /* kill off the idle ones */ - ap_mpm_pod_killpg(pod, ap_max_daemons_limit); - - /* This is mostly for debugging... so that we know what is still - * gracefully dealing with existing request. This will break - * in a very nasty way if we ever have the scoreboard totally - * file-based (no shared memory) - */ - for (index = 0; index < ap_daemons_limit; ++index) { - if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) { - ap_scoreboard_image->servers[index][0].status = SERVER_GRACEFUL; - } - } - } - else { - /* Kill 'em off */ - if (unixd_killpg(getpgrp(), SIGHUP) < 0) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP"); - } - ap_reclaim_child_processes(0); /* Not when just starting up */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "SIGHUP received. Attempting to restart"); - } - - return 0; -} - -/* This really should be a post_config hook, but the error log is already - * redirected by that point, so we need to do this in the open_logs phase. - */ -static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - apr_status_t rv; - - pconf = p; - ap_server_conf = s; - - if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, - NULL, "no listening sockets available, shutting down"); - return DONE; - } - - if ((rv = ap_mpm_pod_open(pconf, &pod))) { - ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, - "Could not open pipe-of-death."); - return DONE; - } - return OK; -} - -static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) -{ - static int restart_num = 0; - int no_detach, debug, foreground; - apr_status_t rv; - - mpm_state = AP_MPMQ_STARTING; - - debug = ap_exists_config_define("DEBUG"); - - if (debug) { - foreground = one_process = 1; - no_detach = 0; - } - else - { - no_detach = ap_exists_config_define("NO_DETACH"); - one_process = ap_exists_config_define("ONE_PROCESS"); - foreground = ap_exists_config_define("FOREGROUND"); - } - - /* sigh, want this only the second time around */ - if (restart_num++ == 1) { - is_graceful = 0; - - if (!one_process && !foreground) { - rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND - : APR_PROC_DETACH_DAEMONIZE); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "apr_proc_detach failed"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - - parent_pid = ap_my_pid = getpid(); - } - - unixd_pre_config(ptemp); - ap_listen_pre_config(); - ap_daemons_to_start = DEFAULT_START_DAEMON; - ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON; - ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON; - ap_daemons_limit = server_limit; - ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - return OK; -} - -static void prefork_hooks(apr_pool_t *p) -{ - /* The prefork open_logs phase must run before the core's, or stderr - * will be redirected to a file, and the messages won't print to the - * console. - */ - static const char *const aszSucc[] = {"core.c", NULL}; - -#ifdef AUX3 - (void) set42sig(); -#endif - - ap_hook_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); - /* we need to set the MPM state before other pre-config hooks use MPM query - * to retrieve it, so register as REALLY_FIRST - */ - ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); -} - -static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_to_start = atoi(arg); - return NULL; -} - -static const char *set_min_free_servers(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_min_free = atoi(arg); - if (ap_daemons_min_free <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareServers set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - ap_daemons_min_free = 1; - } - - return NULL; -} - -static const char *set_max_free_servers(cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_max_free = atoi(arg); - return NULL; -} - -static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_limit = atoi(arg); - if (ap_daemons_limit > server_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients of %d exceeds ServerLimit value " - "of %d servers,", ap_daemons_limit, server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering MaxClients to %d. To increase, please " - "see the ServerLimit", server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " directive."); - ap_daemons_limit = server_limit; - } - else if (ap_daemons_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require MaxClients > 0, setting to 1"); - ap_daemons_limit = 1; - } - return NULL; -} - -static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_server_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_server_limit = atoi(arg); - /* you cannot change ServerLimit across a restart; ignore - * any such attempts - */ - if (first_server_limit && - tmp_server_limit != server_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - server_limit = tmp_server_limit; - - if (server_limit > MAX_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ServerLimit of %d exceeds compile time limit " - "of %d servers,", server_limit, MAX_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); - server_limit = MAX_SERVER_LIMIT; - } - else if (server_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ServerLimit > 0, setting to 1"); - server_limit = 1; - } - return NULL; -} - -static const command_rec prefork_cmds[] = { -UNIX_DAEMON_COMMANDS, -LISTEN_COMMANDS, -AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, - "Number of child processes launched at server startup"), -AP_INIT_TAKE1("MinSpareServers", set_min_free_servers, NULL, RSRC_CONF, - "Minimum number of idle children, to handle request spikes"), -AP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF, - "Maximum number of idle children"), -AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, - "Maximum number of children alive at the same time"), -AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, - "Maximum value of MaxClients for this run of Apache"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_prefork_module = { - MPM20_MODULE_STUFF, - ap_mpm_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - prefork_cmds, /* command apr_table_t */ - prefork_hooks, /* register hooks */ -}; diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.c b/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.c deleted file mode 100644 index a352dd1b..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.c +++ /dev/null @@ -1,697 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef WIN32 - -/* - * Win9xConHook.dll - a hook proc to clean up Win95/98 console behavior. - * - * It is well(?) documented by Microsoft that the Win9x HandlerRoutine - * hooked by the SetConsoleCtrlHandler never receives the CTRL_CLOSE_EVENT, - * CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT signals. - * - * It is possible to have a second window to monitor the WM_ENDSESSION - * message, but the close button still fails.. - * - * There is a 16bit polling method for the close window option, but this - * is CPU intensive and requires thunking. - * - * Attempts to subclass the 'tty' console fail, since that message thread - * is actually owned by the 16 bit winoldap.mod process, although the - * window reports it is owned by the process/thread of the console app. - * - * Win9xConHook is thunks the WM_CLOSE and WM_ENDSESSION messages, - * first through a window hook procedure in the winoldap context, into - * a subclass WndProc, and on to a second hidden monitor window in the - * console application's context that dispatches them to the console app's - * registered HandlerRoutine. - */ - -/* This debugging define turns on output to COM1, although you better init - * the port first (even using hyperterm). It's the only way to catch the - * goings on within system logoff/shutdown. - * #define DBG 1 - */ - -#include <windows.h> - -/* Variables used within any process context: - * hookwndmsg is a shared message to send Win9xConHook signals - * origwndprop is a wndprop atom to store the orig wndproc of the tty - * hookwndprop is a wndprop atom to store the hwnd of the hidden child - * is_service reminds us to unmark this process on the way out - */ -static UINT hookwndmsg = 0; -static LPCTSTR origwndprop; -static LPCTSTR hookwndprop; -static BOOL is_service = 0; -//static HMODULE hmodThis = NULL; - -/* Variables used within the tty processes' context: - * is_tty flags this process; -1 == unknown, 1 == if tty, 0 == if not - * hw_tty is the handle of the top level tty in this process context - * is_subclassed is toggled to assure DllMain removes the subclass on unload - * hmodLock is there to try and prevent this dll from being unloaded if the - * hook is removed while we are subclassed - */ -static int is_tty = -1; -static HWND hwtty = NULL; -static BOOL is_subclassed = 0; - -// This simply causes a gpfault the moment it tries to FreeLibrary within -// the subclass procedure ... not good. -//static HMODULE hmodLock = NULL; - -/* Variables used within the service or console app's context: - * hmodHook is the instance handle of this module for registering the hooks - * hhkGetMessage is the hook handle for catching Posted messages - * hhkGetMessage is the hook handle for catching Sent messages - * monitor_hwnd is the invisible window that handles our tty messages - * the tty_info strucure is used to pass args into the hidden window's thread - */ -static HMODULE hmodHook = NULL; -static HHOOK hhkGetMessage; -//static HHOOK hhkCallWndProc; -static HWND monitor_hwnd = NULL; - -typedef struct { - PHANDLER_ROUTINE phandler; - HINSTANCE instance; - HWND parent; - INT type; - LPCSTR name; -} tty_info; - -/* These are the GetWindowLong offsets for the hidden window's internal info - * gwltty_phandler is the address of the app's HandlerRoutine - * gwltty_ttywnd is the tty this hidden window will handle messages from - */ -#define gwltty_phandler 0 -#define gwltty_ttywnd 4 - -/* Forward declaration prototypes for internal functions - */ -static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd); -static LRESULT WINAPI RegisterWindows9xService(BOOL set_service); -static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg, - WPARAM wParam, LPARAM lParam); -static DWORD WINAPI ttyConsoleCtrlThread(LPVOID tty); -static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, - WPARAM wParam, LPARAM lParam); -static int HookProc(int hc, HWND *hwnd, UINT *msg, - WPARAM *wParam, LPARAM *lParam); -#ifdef DBG -static VOID DbgPrintf(LPTSTR fmt, ...); -#endif - - -/* DllMain is invoked by every process in the entire system that is hooked - * by our window hooks, notably the tty processes' context, and by the user - * who wants tty messages (the app). Keep it light and simple. - */ -BOOL __declspec(dllexport) APIENTRY DllMain(HINSTANCE hModule, ULONG ulReason, - LPVOID pctx) -{ - if (ulReason == DLL_PROCESS_ATTACH) - { - //hmodThis = hModule; - if (!hookwndmsg) { - origwndprop = MAKEINTATOM(GlobalAddAtom("Win9xConHookOrigProc")); - hookwndprop = MAKEINTATOM(GlobalAddAtom("Win9xConHookThunkWnd")); - hookwndmsg = RegisterWindowMessage("Win9xConHookMsg"); - } -#ifdef DBG -// DbgPrintf("H ProcessAttach:%8.8x\r\n", -// GetCurrentProcessId()); -#endif - } - else if ( ulReason == DLL_PROCESS_DETACH ) - { -#ifdef DBG -// DbgPrintf("H ProcessDetach:%8.8x\r\n", GetCurrentProcessId()); -#endif - if (monitor_hwnd) - SendMessage(monitor_hwnd, WM_DESTROY, 0, 0); - if (is_subclassed) - SendMessage(hwtty, hookwndmsg, 0, (LPARAM)hwtty); - if (hmodHook) - { - if (hhkGetMessage) { - UnhookWindowsHookEx(hhkGetMessage); - hhkGetMessage = NULL; - } - //if (hhkCallWndProc) { - // UnhookWindowsHookEx(hhkCallWndProc); - // hhkCallWndProc = NULL; - //} - FreeLibrary(hmodHook); - hmodHook = NULL; - } - if (is_service) - RegisterWindows9xService(FALSE); - if (hookwndmsg) { - GlobalDeleteAtom((ATOM)origwndprop); - GlobalDeleteAtom((ATOM)hookwndprop); - hookwndmsg = 0; - } - } - return TRUE; -} - - -/* This group of functions are provided for the service/console app - * to register itself a HandlerRoutine to accept tty or service messages - */ - - -/* Exported function that creates a Win9x 'service' via a hidden window, - * that notifies the process via the HandlerRoutine messages. - */ -BOOL __declspec(dllexport) WINAPI Windows9xServiceCtrlHandler( - PHANDLER_ROUTINE phandler, - LPCSTR name) -{ - /* If we have not yet done so */ - FreeConsole(); - - if (name) - { - DWORD tid; - HANDLE hThread; - /* NOTE: this is static so the module can continue to - * access these args while we go on to other things - */ - static tty_info tty; - tty.instance = GetModuleHandle(NULL); - tty.phandler = phandler; - tty.parent = NULL; - tty.name = name; - tty.type = 2; - RegisterWindows9xService(TRUE); - hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread, - (LPVOID)&tty, 0, &tid); - if (hThread) - { - CloseHandle(hThread); - return TRUE; - } - } - else /* remove */ - { - if (monitor_hwnd) - SendMessage(monitor_hwnd, WM_DESTROY, 0, 0); - RegisterWindows9xService(FALSE); - return TRUE; - } - return FALSE; -} - - -/* Exported function that registers a HandlerRoutine to accept missing - * Win9x CTRL_EVENTs from the tty window, as NT does without a hassle. - * If add is 1 or 2, register the handler, if 2 also mark it as a service. - * If add is 0 deregister the handler, and unmark if a service - */ -BOOL __declspec(dllexport) WINAPI FixConsoleCtrlHandler( - PHANDLER_ROUTINE phandler, - INT add) -{ - HWND parent; - - if (add) - { - HANDLE hThread; - DWORD tid; - /* NOTE: this is static so the module can continue to - * access these args while we go on to other things - */ - static tty_info tty; - EnumWindows(EnumttyWindow, (LPARAM)&parent); - if (!parent) { -#ifdef DBG - DbgPrintf("A EnumttyWindow failed (%d)\r\n", GetLastError()); -#endif - return FALSE; - } - tty.instance = GetModuleHandle(NULL); - tty.phandler = phandler; - tty.parent = parent; - tty.type = add; - if (add == 2) { - tty.name = "ttyService"; - RegisterWindows9xService(TRUE); - } - else - tty.name = "ttyMonitor"; - hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread, - (LPVOID)&tty, 0, &tid); - if (!hThread) - return FALSE; - CloseHandle(hThread); - hmodHook = LoadLibrary("Win9xConHook.dll"); - if (hmodHook) - { - hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE, - (HOOKPROC)GetProcAddress(hmodHook, "GetMsgProc"), hmodHook, 0); - //hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC, - // (HOOKPROC)GetProcAddress(hmodHook, "CallWndProc"), hmodHook, 0); - } - return TRUE; - } - else /* remove */ - { - if (monitor_hwnd) { - SendMessage(monitor_hwnd, WM_DESTROY, 0, 0); - } - if (hmodHook) - { - if (hhkGetMessage) { - UnhookWindowsHookEx(hhkGetMessage); - hhkGetMessage = NULL; - } - //if (hhkCallWndProc) { - // UnhookWindowsHookEx(hhkCallWndProc); - // hhkCallWndProc = NULL; - //} - FreeLibrary(hmodHook); - hmodHook = NULL; - } - if (is_service) - RegisterWindows9xService(FALSE); - return TRUE; - } - return FALSE; -} - - -/* The following internal helpers are only used within the app's context - */ - -/* ttyConsoleCreateThread is the process that runs within the user app's - * context. It creates and pumps the messages of a hidden monitor window, - * watching for messages from the system, or the associated subclassed tty - * window. Things can happen in our context that can't be done from the - * tty's context, and visa versa, so the subclass procedure and this hidden - * window work together to make it all happen. - */ -static DWORD WINAPI ttyConsoleCtrlThread(LPVOID tty) -{ - WNDCLASS wc; - MSG msg; - wc.style = CS_GLOBALCLASS; - wc.lpfnWndProc = ttyConsoleCtrlWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 8; - wc.hInstance = NULL; - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - if (((tty_info*)tty)->parent) - wc.lpszClassName = "ttyConHookChild"; - else - wc.lpszClassName = "ApacheWin95ServiceMonitor"; - - if (!RegisterClass(&wc)) { -#ifdef DBG - DbgPrintf("A proc %8.8x Error creating class %s (%d)\r\n", - GetCurrentProcessId(), wc.lpszClassName, GetLastError()); -#endif - return 0; - } - - /* Create an invisible window */ - monitor_hwnd = CreateWindow(wc.lpszClassName, ((tty_info*)tty)->name, - WS_OVERLAPPED & ~WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, - ((tty_info*)tty)->instance, tty); - - if (!monitor_hwnd) { -#ifdef DBG - DbgPrintf("A proc %8.8x Error creating window %s %s (%d)\r\n", - GetCurrentProcessId(), wc.lpszClassName, - ((tty_info*)tty)->name, GetLastError()); -#endif - return 0; - } - - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - /* Tag again as deleted, just in case we missed WM_DESTROY */ - monitor_hwnd = NULL; - return 0; -} - - -/* This is the WndProc procedure for our invisible window. - * When our subclasssed tty window receives the WM_CLOSE, WM_ENDSESSION, - * or WM_QUERYENDSESSION messages, the message is dispatched to our hidden - * window (this message process), and we call the installed HandlerRoutine - * that was registered by the app. - */ -static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg, - WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_CREATE) - { - tty_info *tty = (tty_info*)(((LPCREATESTRUCT)lParam)->lpCreateParams); - SetWindowLong(hwnd, gwltty_phandler, (LONG)tty->phandler); - SetWindowLong(hwnd, gwltty_ttywnd, (LONG)tty->parent); -#ifdef DBG - DbgPrintf("A proc %8.8x created %8.8x %s for tty wnd %8.8x\r\n", - GetCurrentProcessId(), hwnd, - tty->name, tty->parent); -#endif - if (tty->parent) { - SetProp(tty->parent, hookwndprop, hwnd); - PostMessage(tty->parent, hookwndmsg, - tty->type, (LPARAM)tty->parent); - } - return 0; - } - else if (msg == WM_DESTROY) - { - HWND parent = (HWND)GetWindowLong(hwnd, gwltty_ttywnd); -#ifdef DBG - DbgPrintf("A proc %8.8x destroyed %8.8x ttyConHookChild\r\n", - GetCurrentProcessId(), hwnd); -#endif - if (parent) { - RemoveProp(parent, hookwndprop); - SendMessage(parent, hookwndmsg, 0, (LPARAM)parent); - } - monitor_hwnd = NULL; - } - else if (msg == WM_CLOSE) - { - PHANDLER_ROUTINE phandler = - (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); - LRESULT rv = phandler(CTRL_CLOSE_EVENT); -#ifdef DBG - DbgPrintf("A proc %8.8x invoked CTRL_CLOSE_EVENT " - "returning %d\r\n", - GetCurrentProcessId(), rv); -#endif - if (rv) - return !rv; - } - else if ((msg == WM_QUERYENDSESSION) || (msg == WM_ENDSESSION)) - { - if (lParam & ENDSESSION_LOGOFF) - { - PHANDLER_ROUTINE phandler = - (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); - LRESULT rv = phandler(CTRL_LOGOFF_EVENT); -#ifdef DBG - DbgPrintf("A proc %8.8x invoked CTRL_LOGOFF_EVENT " - "returning %d\r\n", - GetCurrentProcessId(), rv); -#endif - if (rv) - return ((msg == WM_QUERYENDSESSION) ? rv : !rv); - } - else - { - PHANDLER_ROUTINE phandler = - (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); - LRESULT rv = phandler(CTRL_SHUTDOWN_EVENT); -#ifdef DBG - DbgPrintf("A proc %8.8x invoked CTRL_SHUTDOWN_EVENT " - "returning %d\r\n", GetCurrentProcessId(), rv); -#endif - if (rv) - return ((msg == WM_QUERYENDSESSION) ? rv : !rv); - } - } - return (DefWindowProc(hwnd, msg, wParam, lParam)); -} - - -/* The following internal helpers are invoked by the hooked tty and our app - */ - - -/* Register or deregister the current process as a Windows9x style service. - * Experience shows this call is ignored across processes, so the second - * arg to RegisterServiceProcess (process group id) is effectively useless. - */ -static LRESULT WINAPI RegisterWindows9xService(BOOL set_service) -{ - static HINSTANCE hkernel; - static DWORD (WINAPI *register_service_process)(DWORD, DWORD) = NULL; - BOOL rv; - - if (set_service == is_service) - return 1; - -#ifdef DBG - DbgPrintf("R %s proc %8.8x as a service\r\n", - set_service ? "installing" : "removing", - GetCurrentProcessId()); -#endif - - if (!register_service_process) - { - /* Obtain a handle to the kernel library */ - hkernel = LoadLibrary("KERNEL32.DLL"); - if (!hkernel) - return 0; - - /* Find the RegisterServiceProcess function */ - register_service_process = (DWORD (WINAPI *)(DWORD, DWORD)) - GetProcAddress(hkernel, "RegisterServiceProcess"); - if (register_service_process == NULL) { - FreeLibrary(hkernel); - return 0; - } - } - - /* Register this process as a service */ - rv = register_service_process(0, set_service != FALSE); - if (rv) - is_service = set_service; - - if (!is_service) - { - /* Unload the kernel library */ - FreeLibrary(hkernel); - register_service_process = NULL; - } - return rv; -} - - -/* - * This function only works when this process is the active process - * (e.g. once it is running a child process, it can no longer determine - * which console window is its own.) - */ -static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd) -{ - char tmp[8]; - if (GetClassName(wnd, tmp, sizeof(tmp)) && !strcmp(tmp, "tty")) - { - DWORD wndproc, thisproc = GetCurrentProcessId(); - GetWindowThreadProcessId(wnd, &wndproc); - if (wndproc == thisproc) { - *((HWND*)retwnd) = wnd; - return FALSE; - } - } - return TRUE; -} - - -/* The remaining code all executes --in the tty's own process context-- - * - * That means special attention must be paid to what it's doing... - */ - -/* Subclass message process for the tty window - * - * This code -handles- WM_CLOSE, WM_ENDSESSION and WM_QUERYENDSESSION - * by dispatching them to the window identified by the hookwndprop - * property atom set against our window. Messages are then dispatched - * to origwndprop property atom we set against the window when we - * injected this subclass. This trick did not work with simply a hook. - */ -static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, - WPARAM wParam, LPARAM lParam) -{ - WNDPROC origproc = (WNDPROC) GetProp(hwnd, origwndprop); - if (!origproc) - return 0; - - if (msg == WM_NCDESTROY - || (msg == hookwndmsg && !LOWORD(wParam) && (HWND)lParam == hwnd)) - { - if (is_subclassed) { -#ifdef DBG - DbgPrintf("W proc %08x hwnd:%08x Subclass removed\r\n", - GetCurrentProcessId(), hwnd); -#endif - if (is_service) - RegisterWindows9xService(FALSE); - SetWindowLong(hwnd, GWL_WNDPROC, (LONG)origproc); - RemoveProp(hwnd, origwndprop); - RemoveProp(hwnd, hookwndprop); - is_subclassed = FALSE; - //if (hmodLock) - // FreeLibrary(hmodLock); - //hmodLock = NULL; - } - } - else if (msg == WM_CLOSE || msg == WM_ENDSESSION - || msg == WM_QUERYENDSESSION) - { - HWND child = (HWND)GetProp(hwnd, hookwndprop); - if (child) { -#ifdef DBG - DbgPrintf("W proc %08x hwnd:%08x forwarded msg:%d\r\n", - GetCurrentProcessId(), hwnd, msg); -#endif - return SendMessage(child, msg, wParam, lParam); - } - } - return CallWindowProc(origproc, hwnd, msg, wParam, lParam); -} - - -/* HookProc, once installed, is responsible for subclassing the system - * tty windows. It generally does nothing special itself, since - * research indicates that it cannot deal well with the messages we are - * interested in, that is, WM_CLOSE, WM_QUERYSHUTDOWN and WM_SHUTDOWN - * of the tty process. - * - * Respond and subclass only when a WM_NULL is received by the window. - */ -int HookProc(int hc, HWND *hwnd, UINT *msg, WPARAM *wParam, LPARAM *lParam) -{ - if (is_tty == -1 && *hwnd) - { - char ttybuf[8]; - HWND htty; - hwtty = *hwnd; - while (htty = GetParent(hwtty)) - hwtty = htty; - is_tty = (GetClassName(hwtty, ttybuf, sizeof(ttybuf)) - && !strcmp(ttybuf, "tty")); -#ifdef DBG - if (is_tty) - DbgPrintf("H proc %08x tracking hwnd %08x\r\n", - GetCurrentProcessId(), hwtty); -#endif - } - - if (*msg == hookwndmsg && *wParam && *lParam == (LPARAM)hwtty && is_tty) - { - WNDPROC origproc = (WNDPROC)GetWindowLong(hwtty, GWL_WNDPROC); - //char myname[MAX_PATH]; - //if (GetModuleFileName(hmodThis, myname, sizeof(myname))) - // hmodLock = LoadLibrary(myname); - SetProp(hwtty, origwndprop, origproc); - SetWindowLong(hwtty, GWL_WNDPROC, (LONG)WndProc); - is_subclassed = TRUE; -#ifdef DBG - DbgPrintf("H proc %08x hwnd:%08x Subclassed\r\n", - GetCurrentProcessId(), hwtty); -#endif - if (LOWORD(*wParam) == 2) - RegisterWindows9xService(TRUE); - } - - return -1; -} - - -/* - * PostMessage Hook: - */ -LRESULT __declspec(dllexport) CALLBACK GetMsgProc(INT hc, WPARAM wParam, - LPARAM lParam) -{ - PMSG pmsg; - - pmsg = (PMSG)lParam; - - if (pmsg) { - int rv = HookProc(hc, &pmsg->hwnd, &pmsg->message, - &pmsg->wParam, &pmsg->lParam); - if (rv != -1) - return rv; - } - /* - * CallNextHookEx apparently ignores the hhook argument, so pass NULL - */ - return CallNextHookEx(NULL, hc, wParam, lParam); -} - - -/* - * SendMessage Hook: - */ -LRESULT __declspec(dllexport) CALLBACK CallWndProc(INT hc, WPARAM wParam, - LPARAM lParam) -{ - PCWPSTRUCT pcwps = (PCWPSTRUCT)lParam; - - if (pcwps) { - int rv = HookProc(hc, &pcwps->hwnd, &pcwps->message, - &pcwps->wParam, &pcwps->lParam); - if (rv != -1) - return rv; - } - /* - * CallNextHookEx apparently ignores the hhook argument, so pass NULL - */ - return CallNextHookEx(NULL, hc, wParam, lParam); -} - - -#ifdef DBG -VOID DbgPrintf( - LPTSTR fmt, - ... - ) -{ - static HANDLE mutex; - va_list marker; - TCHAR szBuf[256]; - DWORD t; - HANDLE gDbgOut; - - va_start(marker, fmt); - wvsprintf(szBuf, fmt, marker); - va_end(marker); - - if (!mutex) - mutex = CreateMutex(NULL, FALSE, "Win9xConHookDbgOut"); - WaitForSingleObject(mutex, INFINITE); - gDbgOut = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, - NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); - WriteFile(gDbgOut, szBuf, strlen(szBuf), &t, NULL); - CloseHandle(gDbgOut); - ReleaseMutex(mutex); -} -#endif - -#endif /* WIN32 */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.def b/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.def deleted file mode 100644 index 85ec1664..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.def +++ /dev/null @@ -1,10 +0,0 @@ -LIBRARY Win9xConHook - -EXETYPE WINDOWS - -EXPORTS - DllMain - GetMsgProc - CallWndProc - FixConsoleCtrlHandler - Windows9xServiceCtrlHandler diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.dsp b/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.dsp deleted file mode 100644 index 77cbacfc..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Win9xConHook" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=Win9xConHook - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Win9xConHook.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Win9xConHook.mak" CFG="Win9xConHook - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Win9xConHook - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "Win9xConHook - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Win9xConHook - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /Fd"Release\Win9xConHook" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /base:"0x1c0f0000" -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /base:"0x1c0f0000" /opt:ref - -!ELSEIF "$(CFG)" == "Win9xConHook - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /Fd"Debug\Win9xConHook" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /debug /base:"0x1c0f0000" -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /debug /base:"0x1c0f0000" - -!ENDIF - -# Begin Target - -# Name "Win9xConHook - Win32 Release" -# Name "Win9xConHook - Win32 Debug" -# Begin Source File - -SOURCE=.\Win9xConHook.c -# End Source File -# Begin Source File - -SOURCE=.\Win9xConHook.def -# End Source File -# Begin Source File - -SOURCE=.\Win9xConHook.h -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.h b/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.h deleted file mode 100644 index e3471034..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/Win9xConHook.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef AP_WIN9XCONHOOK_H -#define AP_WIN9XCONHOOK_H - -#ifdef WIN32 - -/* Windows9xServiceCtrlHandler registers a handler routine, frees the - * console window, and registers this process as a service in Win9x. - * It creats a hidden window of class "ApacheWin95ServiceMonitor" - * and titled by the name passed, which passes the WM_SHUTDOWN message - * through the given HandlerRoutine's CTRL_SHUTDOWN event. - * Call with name of NULL to remove the Service handler. - */ -BOOL WINAPI Windows9xServiceCtrlHandler(PHANDLER_ROUTINE phandler, LPCSTR name); - - -/* FixConsoleControlHandler registers a handler routine with the - * Win9xConHook.dll, creating a hidden window and forwarding the - * WM_ENDSESSION and WM_CLOSE messages to the given HandlerRoutine - * as CTRL_SHUTDOWN_EVENT, CTRL_LOGOFF_EVENT and CTRL_CLOSE_EVENT. - * The application should still use SetConsoleCtrlHandler to grab - * the CTRL_BREAK_EVENT and CTRL_C_EVENT, if desired. - */ -BOOL WINAPI FixConsoleCtrlHandler(PHANDLER_ROUTINE phandler, BOOL add); - - -/* - * Exported PostMessage Hook, never use this directly: - * - * LRESULT CALLBACK GetMsgProc(INT hc, WPARAM wParam, LPARAM lParam); - */ - - -/* - * Exported SendMessage Hook, never use this directly: - * - * LRESULT CALLBACK CallWndProc(INT hc, WPARAM wParam, LPARAM lParam); - */ - -#endif /* WIN32 */ - -#endif AP_WIN9XCONHOOK_H diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/child.c b/rubbos/app/httpd-2.0.64/server/mpm/winnt/child.c deleted file mode 100644 index 266d0b3c..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/child.c +++ /dev/null @@ -1,1167 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef WIN32 - -#define CORE_PRIVATE -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "apr_portable.h" -#include "apr_thread_proc.h" -#include "apr_getopt.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_shm.h" -#include "apr_thread_mutex.h" -#include "ap_mpm.h" -#include "ap_config.h" -#include "ap_listen.h" -#include "mpm_default.h" -#include "mpm_winnt.h" -#include "mpm_common.h" -#include <malloc.h> -#include "apr_atomic.h" - -/* shared with mpm_winnt.c */ -extern DWORD my_pid; - -/* used by parent to signal the child to start and exit */ -/* shared with mpm_winnt.c, but should be private to child.c */ -apr_proc_mutex_t *start_mutex; -HANDLE exit_event; - -/* child_main() should never need to modify is_graceful!?! */ -extern int volatile is_graceful; - -/* Queue for managing the passing of COMP_CONTEXTs between - * the accept and worker threads. - */ -static apr_pool_t *pchild; -static int shutdown_in_progress = 0; -static int workers_may_exit = 0; -static unsigned int g_blocked_threads = 0; -static HANDLE max_requests_per_child_event; - -static apr_thread_mutex_t *child_lock; -static apr_thread_mutex_t *qlock; -static PCOMP_CONTEXT qhead = NULL; -static PCOMP_CONTEXT qtail = NULL; -static int num_completion_contexts = 0; -static int max_num_completion_contexts = 0; -static HANDLE ThreadDispatchIOCP = NULL; -static HANDLE qwait_event = NULL; - - -AP_DECLARE(void) mpm_recycle_completion_context(PCOMP_CONTEXT context) -{ - /* Recycle the completion context. - * - clear the ptrans pool - * - put the context on the queue to be consumed by the accept thread - * Note: - * context->accept_socket may be in a disconnected but reusable - * state so -don't- close it. - */ - if (context) { - apr_pool_clear(context->ptrans); - context->ba = apr_bucket_alloc_create(context->ptrans); - context->next = NULL; - ResetEvent(context->Overlapped.hEvent); - apr_thread_mutex_lock(qlock); - if (qtail) { - qtail->next = context; - } else { - qhead = context; - SetEvent(qwait_event); - } - qtail = context; - apr_thread_mutex_unlock(qlock); - } -} - -AP_DECLARE(PCOMP_CONTEXT) mpm_get_completion_context(void) -{ - apr_status_t rv; - PCOMP_CONTEXT context = NULL; - - while (1) { - /* Grab a context off the queue */ - apr_thread_mutex_lock(qlock); - if (qhead) { - context = qhead; - qhead = qhead->next; - if (!qhead) - qtail = NULL; - } else { - ResetEvent(qwait_event); - } - apr_thread_mutex_unlock(qlock); - - if (!context) { - /* We failed to grab a context off the queue, consider allocating - * a new one out of the child pool. There may be up to - * (ap_threads_per_child + num_listeners) contexts in the system - * at once. - */ - if (num_completion_contexts >= max_num_completion_contexts) { - /* All workers are busy, need to wait for one */ - static int reported = 0; - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, - "Server ran out of threads to serve requests. Consider " - "raising the ThreadsPerChild setting"); - reported = 1; - } - - /* Wait for a worker to free a context. Once per second, give - * the caller a chance to check for shutdown. If the wait - * succeeds, get the context off the queue. It must be available, - * since there's only one consumer. - */ - rv = WaitForSingleObject(qwait_event, 1000); - if (rv == WAIT_OBJECT_0) - continue; - else /* Hopefully, WAIT_TIMEOUT */ - return NULL; - } else { - /* Allocate another context. - * Note: - * Multiple failures in the next two steps will cause the pchild pool - * to 'leak' storage. I don't think this is worth fixing... - */ - apr_allocator_t *allocator; - - apr_thread_mutex_lock(child_lock); - context = (PCOMP_CONTEXT) apr_pcalloc(pchild, sizeof(COMP_CONTEXT)); - - context->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (context->Overlapped.hEvent == NULL) { - /* Hopefully this is a temporary condition ... */ - ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_os_error(), ap_server_conf, - "mpm_get_completion_context: CreateEvent failed."); - - apr_thread_mutex_unlock(child_lock); - return NULL; - } - - /* Create the tranaction pool */ - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - rv = apr_pool_create_ex(&context->ptrans, pchild, NULL, allocator); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_WARNING, rv, ap_server_conf, - "mpm_get_completion_context: Failed to create the transaction pool."); - CloseHandle(context->Overlapped.hEvent); - - apr_thread_mutex_unlock(child_lock); - return NULL; - } - apr_allocator_owner_set(allocator, context->ptrans); - apr_pool_tag(context->ptrans, "transaction"); - context->accept_socket = INVALID_SOCKET; - context->ba = apr_bucket_alloc_create(context->ptrans); - apr_atomic_inc(&num_completion_contexts); - - apr_thread_mutex_unlock(child_lock); - break; - } - } else { - /* Got a context from the queue */ - break; - } - } - - return context; -} - -AP_DECLARE(apr_status_t) mpm_post_completion_context(PCOMP_CONTEXT context, - io_state_e state) -{ - LPOVERLAPPED pOverlapped; - if (context) - pOverlapped = &context->Overlapped; - else - pOverlapped = NULL; - - PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, state, pOverlapped); - return APR_SUCCESS; -} - - -/* - * find_ready_listener() - * Only used by Win9* and should go away when the win9*_accept() function is - * reimplemented using apr_poll(). - */ -static ap_listen_rec *head_listener; - -static APR_INLINE ap_listen_rec *find_ready_listener(fd_set * main_fds) -{ - ap_listen_rec *lr; - SOCKET nsd; - - lr = head_listener; - do { - apr_os_sock_get(&nsd, lr->sd); - if (FD_ISSET(nsd, main_fds)) { - head_listener = lr->next; - if (!head_listener) { - head_listener = ap_listeners; - } - return lr; - } - lr = lr->next; - if (!lr) { - lr = ap_listeners; - } - } while (lr != head_listener); - return NULL; -} - - -/* Windows 9x specific code... - * Accept processing for on Windows 95/98 uses a producer/consumer queue - * model. A single thread accepts connections and queues the accepted socket - * to the accept queue for consumption by a pool of worker threads. - * - * win9x_accept() - * The accept threads runs this function, which accepts connections off - * the network and calls add_job() to queue jobs to the accept_queue. - * add_job()/remove_job() - * Add or remove an accepted socket from the list of sockets - * connected to clients. allowed_globals.jobmutex protects - * against multiple concurrent access to the linked list of jobs. - * win9x_get_connection() - * Calls remove_job() to pull a job from the accept queue. All the worker - * threads block on remove_job. - */ - -typedef struct joblist_s { - struct joblist_s *next; - int sock; -} joblist; - -typedef struct globals_s { - HANDLE jobsemaphore; - joblist *jobhead; - joblist *jobtail; - apr_thread_mutex_t *jobmutex; - int jobcount; -} globals; - -globals allowed_globals = {NULL, NULL, NULL, NULL, 0}; - -#define MAX_SELECT_ERRORS 100 - - -static void add_job(int sock) -{ - joblist *new_job; - - new_job = (joblist *) malloc(sizeof(joblist)); - if (new_job == NULL) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Ouch! Out of memory in add_job()!"); - return; - } - new_job->next = NULL; - new_job->sock = sock; - - apr_thread_mutex_lock(allowed_globals.jobmutex); - - if (allowed_globals.jobtail != NULL) - allowed_globals.jobtail->next = new_job; - allowed_globals.jobtail = new_job; - if (!allowed_globals.jobhead) - allowed_globals.jobhead = new_job; - allowed_globals.jobcount++; - ReleaseSemaphore(allowed_globals.jobsemaphore, 1, NULL); - - apr_thread_mutex_unlock(allowed_globals.jobmutex); -} - - -static int remove_job(void) -{ - joblist *job; - int sock; - - WaitForSingleObject(allowed_globals.jobsemaphore, INFINITE); - apr_thread_mutex_lock(allowed_globals.jobmutex); - - if (shutdown_in_progress && !allowed_globals.jobhead) { - apr_thread_mutex_unlock(allowed_globals.jobmutex); - return (INVALID_SOCKET); - } - job = allowed_globals.jobhead; - ap_assert(job); - allowed_globals.jobhead = job->next; - if (allowed_globals.jobhead == NULL) - allowed_globals.jobtail = NULL; - apr_thread_mutex_unlock(allowed_globals.jobmutex); - sock = job->sock; - free(job); - - return (sock); -} - - -static unsigned int __stdcall win9x_accept(void * dummy) -{ - struct timeval tv; - fd_set main_fds; - int wait_time = 1; - int csd; - SOCKET nsd = INVALID_SOCKET; - struct sockaddr_in sa_client; - int count_select_errors = 0; - int rc; - int clen; - ap_listen_rec *lr; - struct fd_set listenfds; - SOCKET listenmaxfd = INVALID_SOCKET; - - /* Setup the listeners - * ToDo: Use apr_poll() - */ - FD_ZERO(&listenfds); - for (lr = ap_listeners; lr; lr = lr->next) { - if (lr->sd != NULL) { - apr_os_sock_get(&nsd, lr->sd); - FD_SET(nsd, &listenfds); - if (listenmaxfd == INVALID_SOCKET || nsd > listenmaxfd) { - listenmaxfd = nsd; - } - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "Child %d: Listening on port %d.", my_pid, lr->bind_addr->port); - } - } - - head_listener = ap_listeners; - - while (!shutdown_in_progress) { - tv.tv_sec = wait_time; - tv.tv_usec = 0; - memcpy(&main_fds, &listenfds, sizeof(fd_set)); - - rc = select(listenmaxfd + 1, &main_fds, NULL, NULL, &tv); - - if (rc == 0 || (rc == SOCKET_ERROR && APR_STATUS_IS_EINTR(apr_get_netos_error()))) { - count_select_errors = 0; /* reset count of errors */ - continue; - } - else if (rc == SOCKET_ERROR) { - /* A "real" error occurred, log it and increment the count of - * select errors. This count is used to ensure we don't go into - * a busy loop of continuous errors. - */ - ap_log_error(APLOG_MARK, APLOG_INFO, apr_get_netos_error(), ap_server_conf, - "select failed with error %d", apr_get_netos_error()); - count_select_errors++; - if (count_select_errors > MAX_SELECT_ERRORS) { - shutdown_in_progress = 1; - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), ap_server_conf, - "Too many errors in select loop. Child process exiting."); - break; - } - } else { - ap_listen_rec *lr; - - lr = find_ready_listener(&main_fds); - if (lr != NULL) { - /* fetch the native socket descriptor */ - apr_os_sock_get(&nsd, lr->sd); - } - } - - do { - clen = sizeof(sa_client); - csd = accept(nsd, (struct sockaddr *) &sa_client, &clen); - } while (csd < 0 && APR_STATUS_IS_EINTR(apr_get_netos_error())); - - if (csd < 0) { - if (APR_STATUS_IS_ECONNABORTED(apr_get_netos_error())) { - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), ap_server_conf, - "accept: (client socket)"); - } - } - else { - add_job(csd); - } - } - SetEvent(exit_event); - return 0; -} - - -static PCOMP_CONTEXT win9x_get_connection(PCOMP_CONTEXT context) -{ - apr_os_sock_info_t sockinfo; - int len; - - if (context == NULL) { - /* allocate the completion context and the transaction pool */ - apr_allocator_t *allocator; - apr_thread_mutex_lock(child_lock); - context = apr_pcalloc(pchild, sizeof(COMP_CONTEXT)); - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - apr_pool_create_ex(&context->ptrans, pchild, NULL, allocator); - apr_allocator_owner_set(allocator, context->ptrans); - apr_pool_tag(context->ptrans, "transaction"); - apr_thread_mutex_unlock(child_lock); - } - - while (1) { - apr_pool_clear(context->ptrans); - context->ba = apr_bucket_alloc_create(context->ptrans); - context->accept_socket = remove_job(); - if (context->accept_socket == INVALID_SOCKET) { - return NULL; - } - len = sizeof(struct sockaddr); - context->sa_server = apr_palloc(context->ptrans, len); - if (getsockname(context->accept_socket, - context->sa_server, &len)== SOCKET_ERROR) { - ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, - "getsockname failed"); - continue; - } - len = sizeof(struct sockaddr); - context->sa_client = apr_palloc(context->ptrans, len); - if ((getpeername(context->accept_socket, - context->sa_client, &len)) == SOCKET_ERROR) { - ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, - "getpeername failed"); - memset(&context->sa_client, '\0', sizeof(context->sa_client)); - } - sockinfo.os_sock = &context->accept_socket; - sockinfo.local = context->sa_server; - sockinfo.remote = context->sa_client; - sockinfo.family = APR_INET; - sockinfo.type = SOCK_STREAM; - apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); - - return context; - } -} - - -/* Windows NT/2000 specific code... - * Accept processing for on Windows NT uses a producer/consumer queue - * model. An accept thread accepts connections off the network then issues - * PostQueuedCompletionStatus() to awake a thread blocked on the ThreadDispatch - * IOCompletionPort. - * - * winnt_accept() - * One or more accept threads run in this function, each of which accepts - * connections off the network and calls PostQueuedCompletionStatus() to - * queue an io completion packet to the ThreadDispatch IOCompletionPort. - * winnt_get_connection() - * Worker threads block on the ThreadDispatch IOCompletionPort awaiting - * connections to service. - */ -#define MAX_ACCEPTEX_ERR_COUNT 250 -static unsigned int __stdcall winnt_accept(void *lr_) -{ - ap_listen_rec *lr = (ap_listen_rec *)lr_; - apr_os_sock_info_t sockinfo; - PCOMP_CONTEXT context = NULL; - DWORD BytesRead; - SOCKET nlsd; - int rv, err_count = 0; - - apr_os_sock_get(&nlsd, lr->sd); - - while (!shutdown_in_progress) { - if (!context) { - context = mpm_get_completion_context(); - if (!context) { - /* Temporary resource constraint? */ - Sleep(0); - continue; - } - } - - /* Create and initialize the accept socket */ - if (context->accept_socket == INVALID_SOCKET) { - context->accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (context->accept_socket == INVALID_SOCKET) { - /* Another temporary condition? */ - ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_netos_error(), ap_server_conf, - "winnt_accept: Failed to allocate an accept socket. " - "Temporary resource constraint? Try again."); - Sleep(100); - continue; - } - } - - /* AcceptEx on the completion context. The completion context will be - * signaled when a connection is accepted. - */ - if (!AcceptEx(nlsd, context->accept_socket, - context->buff, - 0, - PADDED_ADDR_SIZE, - PADDED_ADDR_SIZE, - &BytesRead, - &context->Overlapped)) { - rv = apr_get_netos_error(); - if ((rv == APR_FROM_OS_ERROR(WSAEINVAL)) || - (rv == APR_FROM_OS_ERROR(WSAENOTSOCK))) { - /* We can get here when: - * 1) the client disconnects early - * 2) TransmitFile does not properly recycle the accept socket (typically - * because the client disconnected) - * 3) there is VPN or Firewall software installed with buggy AcceptEx implementation - * 4) the webserver is using a dynamic address that has changed - */ - ++err_count; - closesocket(context->accept_socket); - context->accept_socket = INVALID_SOCKET; - if (err_count > MAX_ACCEPTEX_ERR_COUNT) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, - "Child %d: Encountered too many errors accepting client connections. " - "Possible causes: dynamic address renewal, or incompatible VPN or firewall software. " - "Try using the Win32DisableAcceptEx directive.", my_pid); - err_count = 0; - } - continue; - } - else if ((rv != APR_FROM_OS_ERROR(ERROR_IO_PENDING)) && - (rv != APR_FROM_OS_ERROR(WSA_IO_PENDING))) { - ++err_count; - closesocket(context->accept_socket); - context->accept_socket = INVALID_SOCKET; - if (err_count > MAX_ACCEPTEX_ERR_COUNT) { - ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "Child %d: Encountered too many errors accepting client connections. " - "Possible causes: Unknown. " - "Try using the Win32DisableAcceptEx directive.", my_pid); - err_count = 0; - } - continue; - } - - /* Wait for pending i/o. - * Wake up once per second to check for shutdown . - * XXX: We should be waiting on exit_event instead of polling - */ - while (1) { - rv = WaitForSingleObject(context->Overlapped.hEvent, 1000); - if (rv == WAIT_OBJECT_0) { - if (context->accept_socket == INVALID_SOCKET) { - /* socket already closed */ - break; - } - if (!GetOverlappedResult((HANDLE)context->accept_socket, - &context->Overlapped, - &BytesRead, FALSE)) { - ap_log_error(APLOG_MARK, APLOG_WARNING, - apr_get_os_error(), ap_server_conf, - "winnt_accept: Asynchronous AcceptEx failed."); - closesocket(context->accept_socket); - context->accept_socket = INVALID_SOCKET; - } - break; - } - /* WAIT_TIMEOUT */ - if (shutdown_in_progress) { - closesocket(context->accept_socket); - context->accept_socket = INVALID_SOCKET; - break; - } - } - if (context->accept_socket == INVALID_SOCKET) { - continue; - } - } - - err_count = 0; - /* Inherit the listen socket settings. Required for - * shutdown() to work - */ - if (setsockopt(context->accept_socket, SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, (char *)&nlsd, - sizeof(nlsd))) { - ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, - "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed."); - /* Not a failure condition. Keep running. */ - } - - /* Get the local & remote address */ - GetAcceptExSockaddrs(context->buff, - 0, - PADDED_ADDR_SIZE, - PADDED_ADDR_SIZE, - &context->sa_server, - &context->sa_server_len, - &context->sa_client, - &context->sa_client_len); - - sockinfo.os_sock = &context->accept_socket; - sockinfo.local = context->sa_server; - sockinfo.remote = context->sa_client; - sockinfo.family = APR_INET; - sockinfo.type = SOCK_STREAM; - apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); - - /* When a connection is received, send an io completion notification to - * the ThreadDispatchIOCP. This function could be replaced by - * mpm_post_completion_context(), but why do an extra function call... - */ - PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_CONNECTION_ACCEPTED, - &context->Overlapped); - context = NULL; - } - if (!shutdown_in_progress) { - /* Yow, hit an irrecoverable error! Tell the child to die. */ - SetEvent(exit_event); - } - ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, - "Child %d: Accept thread exiting.", my_pid); - return 0; -} - - -static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context) -{ - int rc; - DWORD BytesRead; - DWORD CompKey; - LPOVERLAPPED pol; - - mpm_recycle_completion_context(context); - - apr_atomic_inc(&g_blocked_threads); - while (1) { - if (workers_may_exit) { - apr_atomic_dec(&g_blocked_threads); - return NULL; - } - rc = GetQueuedCompletionStatus(ThreadDispatchIOCP, &BytesRead, &CompKey, - &pol, INFINITE); - if (!rc) { - rc = apr_get_os_error(); - ap_log_error(APLOG_MARK,APLOG_DEBUG, rc, ap_server_conf, - "Child %d: GetQueuedComplationStatus returned %d", my_pid, rc); - continue; - } - - switch (CompKey) { - case IOCP_CONNECTION_ACCEPTED: - context = CONTAINING_RECORD(pol, COMP_CONTEXT, Overlapped); - break; - case IOCP_SHUTDOWN: - apr_atomic_dec(&g_blocked_threads); - return NULL; - default: - apr_atomic_dec(&g_blocked_threads); - return NULL; - } - break; - } - apr_atomic_dec(&g_blocked_threads); - - return context; -} - - -/* - * worker_main() - * Main entry point for the worker threads. Worker threads block in - * win*_get_connection() awaiting a connection to service. - */ -static unsigned int __stdcall worker_main(void *thread_num_val) -{ - static int requests_this_child = 0; - PCOMP_CONTEXT context = NULL; - int thread_num = (int)thread_num_val; - ap_sb_handle_t *sbh; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, - "Child %d: Worker thread %ld starting.", my_pid, thread_num); - while (1) { - conn_rec *c; - apr_int32_t disconnected; - - ap_update_child_status_from_indexes(0, thread_num, SERVER_READY, NULL); - - /* Grab a connection off the network */ - if (use_acceptex) { - context = winnt_get_connection(context); - } - else { - context = win9x_get_connection(context); - } - if (!context) { - /* Time for the thread to exit */ - break; - } - - /* Have we hit MaxRequestPerChild connections? */ - if (ap_max_requests_per_child) { - requests_this_child++; - if (requests_this_child > ap_max_requests_per_child) { - SetEvent(max_requests_per_child_event); - } - } - - ap_create_sb_handle(&sbh, context->ptrans, 0, thread_num); - c = ap_run_create_connection(context->ptrans, ap_server_conf, - context->sock, thread_num, sbh, - context->ba); - - if (c) { - ap_process_connection(c, context->sock); - apr_socket_opt_get(context->sock, APR_SO_DISCONNECTED, - &disconnected); - if (!disconnected) { - context->accept_socket = INVALID_SOCKET; - ap_lingering_close(c); - } - else if (!use_acceptex) { - /* If the socket is disconnected but we are not using acceptex, - * we cannot reuse the socket. Disconnected sockets are removed - * from the apr_socket_t struct by apr_sendfile() to prevent the - * socket descriptor from being inadvertently closed by a call - * to apr_socket_close(), so close it directly. - */ - closesocket(context->accept_socket); - context->accept_socket = INVALID_SOCKET; - } - } - else { - /* ap_run_create_connection closes the socket on failure */ - context->accept_socket = INVALID_SOCKET; - } - } - - ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD, - (request_rec *) NULL); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, - "Child %d: Worker thread %ld exiting.", my_pid, thread_num); - return 0; -} - - -static void cleanup_thread(HANDLE *handles, int *thread_cnt, int thread_to_clean) -{ - int i; - - CloseHandle(handles[thread_to_clean]); - for (i = thread_to_clean; i < ((*thread_cnt) - 1); i++) - handles[i] = handles[i + 1]; - (*thread_cnt)--; -} - - -/* - * child_main() - * Entry point for the main control thread for the child process. - * This thread creates the accept thread, worker threads and - * monitors the child process for maintenance and shutdown - * events. - */ -static void create_listener_thread() -{ - int tid; - int num_listeners = 0; - if (!use_acceptex) { - _beginthreadex(NULL, 0, win9x_accept, - NULL, 0, &tid); - } else { - /* Start an accept thread per listener - * XXX: Why would we have a NULL sd in our listeners? - */ - ap_listen_rec *lr; - - /* Number of completion_contexts allowed in the system is - * (ap_threads_per_child + num_listeners). We need the additional - * completion contexts to prevent server hangs when ThreadsPerChild - * is configured to something less than or equal to the number - * of listeners. This is not a usual case, but people have - * encountered it. - * */ - for (lr = ap_listeners; lr ; lr = lr->next) { - num_listeners++; - } - max_num_completion_contexts = ap_threads_per_child + num_listeners; - - /* Now start a thread per listener */ - for (lr = ap_listeners; lr; lr = lr->next) { - if (lr->sd != NULL) { - _beginthreadex(NULL, 1000, winnt_accept, - (void *) lr, 0, &tid); - } - } - } -} - - -void child_main(apr_pool_t *pconf) -{ - apr_status_t status; - apr_hash_t *ht; - ap_listen_rec *lr; - HANDLE child_events[2]; - HANDLE *child_handles; - int listener_started = 0; - int threads_created = 0; - int watch_thread; - int time_remains; - int cld; - int tid; - int rv; - int i; - - apr_pool_create(&pchild, pconf); - apr_pool_tag(pchild, "pchild"); - - ap_run_child_init(pchild, ap_server_conf); - ht = apr_hash_make(pchild); - - /* Initialize the child_events */ - max_requests_per_child_event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!max_requests_per_child_event) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Failed to create a max_requests event.", my_pid); - exit(APEXIT_CHILDINIT); - } - child_events[0] = exit_event; - child_events[1] = max_requests_per_child_event; - - allowed_globals.jobsemaphore = CreateSemaphore(NULL, 0, 1000000, NULL); - apr_thread_mutex_create(&allowed_globals.jobmutex, - APR_THREAD_MUTEX_DEFAULT, pchild); - - /* - * Wait until we have permission to start accepting connections. - * start_mutex is used to ensure that only one child ever - * goes into the listen/accept loop at once. - */ - status = apr_proc_mutex_lock(start_mutex); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_ERR, status, ap_server_conf, - "Child %d: Failed to acquire the start_mutex. Process will exit.", my_pid); - exit(APEXIT_CHILDINIT); - } - ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Acquired the start mutex.", my_pid); - - /* - * Create the worker thread dispatch IOCompletionPort - * on Windows NT/2000 - */ - if (use_acceptex) { - /* Create the worker thread dispatch IOCP */ - ThreadDispatchIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, - NULL, - 0, - 0); /* CONCURRENT ACTIVE THREADS */ - apr_thread_mutex_create(&qlock, APR_THREAD_MUTEX_DEFAULT, pchild); - qwait_event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!qwait_event) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Failed to create a qwait event.", my_pid); - exit(APEXIT_CHILDINIT); - } - } - - /* - * Create the pool of worker threads - */ - ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Starting %d worker threads.", my_pid, ap_threads_per_child); - child_handles = (HANDLE) apr_pcalloc(pchild, ap_threads_per_child * sizeof(int)); - apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, pchild); - - while (1) { - for (i = 0; i < ap_threads_per_child; i++) { - int *score_idx; - int status = ap_scoreboard_image->servers[0][i].status; - if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { - continue; - } - ap_update_child_status_from_indexes(0, i, SERVER_STARTING, NULL); - child_handles[i] = (HANDLE) _beginthreadex(NULL, 0, worker_main, - (void *) i, 0, &tid); - if (child_handles[i] == 0) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: _beginthreadex failed. Unable to create all worker threads. " - "Created %d of the %d threads requested with the ThreadsPerChild configuration directive.", - my_pid, threads_created, ap_threads_per_child); - ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); - goto shutdown; - } - threads_created++; - /* Save the score board index in ht keyed to the thread handle. We need this - * when cleaning up threads down below... - */ - apr_thread_mutex_lock(child_lock); - score_idx = apr_pcalloc(pchild, sizeof(int)); - *score_idx = i; - apr_hash_set(ht, &child_handles[i], sizeof(HANDLE), score_idx); - apr_thread_mutex_unlock(child_lock); - } - /* Start the listener only when workers are available */ - if (!listener_started && threads_created) { - create_listener_thread(); - listener_started = 1; - winnt_mpm_state = AP_MPMQ_RUNNING; - } - if (threads_created == ap_threads_per_child) { - break; - } - /* Check to see if the child has been told to exit */ - if (WaitForSingleObject(exit_event, 0) != WAIT_TIMEOUT) { - break; - } - /* wait for previous generation to clean up an entry in the scoreboard */ - apr_sleep(1 * APR_USEC_PER_SEC); - } - - /* Wait for one of three events: - * exit_event: - * The exit_event is signaled by the parent process to notify - * the child that it is time to exit. - * - * max_requests_per_child_event: - * This event is signaled by the worker threads to indicate that - * the process has handled MaxRequestsPerChild connections. - * - * TIMEOUT: - * To do periodic maintenance on the server (check for thread exits, - * number of completion contexts, etc.) - * - * XXX: thread exits *aren't* being checked. - * - * XXX: other_child - we need the process handles to the other children - * in order to map them to apr_proc_other_child_read (which is not - * named well, it's more like a_p_o_c_died.) - * - * XXX: however - if we get a_p_o_c handle inheritance working, and - * the parent process creates other children and passes the pipes - * to our worker processes, then we have no business doing such - * things in the child_main loop, but should happen in master_main. - */ - while (1) { -#if !APR_HAS_OTHER_CHILD - rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, INFINITE); - cld = rv - WAIT_OBJECT_0; -#else - rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, 1000); - cld = rv - WAIT_OBJECT_0; - if (rv == WAIT_TIMEOUT) { - apr_proc_other_child_check(); - } - else -#endif - if (rv == WAIT_FAILED) { - /* Something serious is wrong */ - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: WAIT_FAILED -- shutting down server", my_pid); - break; - } - else if (cld == 0) { - /* Exit event was signaled */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Exit event signaled. Child process is ending.", my_pid); - break; - } - else { - /* MaxRequestsPerChild event set by the worker threads. - * Signal the parent to restart - */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Process exiting because it reached " - "MaxRequestsPerChild. Signaling the parent to " - "restart a new child process.", my_pid); - ap_signal_parent(SIGNAL_PARENT_RESTART); - break; - } - } - - /* - * Time to shutdown the child process - */ - - shutdown: - - winnt_mpm_state = AP_MPMQ_STOPPING; - /* Setting is_graceful will cause threads handling keep-alive connections - * to close the connection after handling the current request. - */ - is_graceful = 1; - - /* Close the listening sockets. Note, we must close the listeners - * before closing any accept sockets pending in AcceptEx to prevent - * memory leaks in the kernel. - */ - for (lr = ap_listeners; lr ; lr = lr->next) { - apr_socket_close(lr->sd); - } - - /* Shutdown listener threads and pending AcceptEx socksts - * but allow the worker threads to continue consuming from - * the queue of accepted connections. - */ - shutdown_in_progress = 1; - - Sleep(1000); - - /* Tell the worker threads to exit */ - workers_may_exit = 1; - - /* Release the start_mutex to let the new process (in the restart - * scenario) a chance to begin accepting and servicing requests - */ - rv = apr_proc_mutex_unlock(start_mutex); - if (rv == APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_NOTICE, rv, ap_server_conf, - "Child %d: Released the start mutex", my_pid); - } - else { - ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "Child %d: Failure releasing the start mutex", my_pid); - } - - /* Shutdown the worker threads */ - if (!use_acceptex) { - for (i = 0; i < threads_created; i++) { - add_job(INVALID_SOCKET); - } - } - else { /* Windows NT/2000 */ - /* Post worker threads blocked on the ThreadDispatch IOCompletion port */ - while (g_blocked_threads > 0) { - ap_log_error(APLOG_MARK,APLOG_INFO, APR_SUCCESS, ap_server_conf, - "Child %d: %d threads blocked on the completion port", my_pid, g_blocked_threads); - for (i=g_blocked_threads; i > 0; i--) { - PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_SHUTDOWN, NULL); - } - Sleep(1000); - } - /* Empty the accept queue of completion contexts */ - apr_thread_mutex_lock(qlock); - while (qhead) { - CloseHandle(qhead->Overlapped.hEvent); - closesocket(qhead->accept_socket); - qhead = qhead->next; - } - apr_thread_mutex_unlock(qlock); - } - - /* Give busy threads a chance to service their connections, - * (no more than the global server timeout period which - * we track in msec remaining). - */ - watch_thread = 0; - time_remains = (int)(ap_server_conf->timeout / APR_TIME_C(1000)); - - while (threads_created) - { - int nFailsafe = MAXIMUM_WAIT_OBJECTS; - DWORD dwRet; - - /* Every time we roll over to wait on the first group - * of MAXIMUM_WAIT_OBJECTS threads, take a breather, - * and infrequently update the error log. - */ - if (watch_thread >= threads_created) { - if ((time_remains -= 100) < 0) - break; - - /* Every 30 seconds give an update */ - if ((time_remains % 30000) == 0) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, - ap_server_conf, - "Child %d: Waiting %d more seconds " - "for %d worker threads to finish.", - my_pid, time_remains / 1000, threads_created); - } - /* We'll poll from the top, 10 times per second */ - Sleep(100); - watch_thread = 0; - } - - /* Fairness, on each iteration we will pick up with the thread - * after the one we just removed, even if it's a single thread. - * We don't block here. - */ - dwRet = WaitForMultipleObjects(min(threads_created - watch_thread, - MAXIMUM_WAIT_OBJECTS), - child_handles + watch_thread, 0, 0); - - if (dwRet == WAIT_FAILED) { - break; - } - if (dwRet == WAIT_TIMEOUT) { - /* none ready */ - watch_thread += MAXIMUM_WAIT_OBJECTS; - continue; - } - else if (dwRet >= WAIT_ABANDONED_0) { - /* We just got the ownership of the object, which - * should happen at most MAXIMUM_WAIT_OBJECTS times. - * It does NOT mean that the object is signaled. - */ - if ((nFailsafe--) < 1) - break; - } - else { - watch_thread += (dwRet - WAIT_OBJECT_0); - if (watch_thread >= threads_created) - break; - cleanup_thread(child_handles, &threads_created, watch_thread); - } - } - - /* Kill remaining threads off the hard way */ - if (threads_created) { - ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Terminating %d threads that failed to exit.", - my_pid, threads_created); - } - for (i = 0; i < threads_created; i++) { - int *score_idx; - TerminateThread(child_handles[i], 1); - CloseHandle(child_handles[i]); - /* Reset the scoreboard entry for the thread we just whacked */ - score_idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE)); - ap_update_child_status_from_indexes(0, *score_idx, SERVER_DEAD, NULL); - } - ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: All worker threads have exited.", my_pid); - - CloseHandle(allowed_globals.jobsemaphore); - apr_thread_mutex_destroy(allowed_globals.jobmutex); - apr_thread_mutex_destroy(child_lock); - - if (use_acceptex) { - apr_thread_mutex_destroy(qlock); - CloseHandle(qwait_event); - } - - apr_pool_destroy(pchild); - CloseHandle(exit_event); -} - -#endif /* def WIN32 */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm.h deleted file mode 100644 index 2cae7a8e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_H -#define APACHE_MPM_H - -/* mpm.h is the place to make declarations that are MPM specific but that must be - * shared with non-mpm specific code in the server. Hummm, perhaps we can - * move most of this stuff to mpm_common.h? - */ - -#include "scoreboard.h" - -#define MPM_NAME "WinNT" - -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_MAX_MEM_FREE - -extern int ap_threads_per_child; -extern int ap_thread_limit; -extern server_rec *ap_server_conf; - -#endif /* APACHE_MPM_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_default.h deleted file mode 100644 index 847bd732..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_default.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Default limit on the maximum setting of the ThreadsPerChild configuration - * directive. This limit can be overridden with the ThreadLimit directive. - * This limit directly influences the amount of shared storage that is allocated - * for the scoreboard. DEFAULT_THREAD_LIMIT represents a good compromise - * between scoreboard size and the ability of the server to handle the most - * common installation requirements. - */ -#ifndef DEFAULT_THREAD_LIMIT -#define DEFAULT_THREAD_LIMIT 1920 -#endif - -/* The ThreadLimit directive can be used to override the DEFAULT_THREAD_LIMIT. - * ThreadLimit cannot be tuned larger than MAX_THREAD_LIMIT. - * This is a sort of compile-time limit to help catch typos. - */ -#ifndef MAX_THREAD_LIMIT -#define MAX_THREAD_LIMIT 15000 -#endif - -/* Number of threads started in the child process in the absence - * of a ThreadsPerChild configuration directive - */ -#ifndef DEFAULT_THREADS_PER_CHILD -#define DEFAULT_THREADS_PER_CHILD 64 -#endif - -/* Max number of child processes allowed. - */ -#define HARD_SERVER_LIMIT 1 - -/* Number of servers to spawn off by default - */ -#ifndef DEFAULT_NUM_DAEMON -#define DEFAULT_NUM_DAEMON 1 -#endif - -/* Check for definition of DEFAULT_REL_RUNTIMEDIR */ -#ifndef DEFAULT_REL_RUNTIMEDIR -#define DEFAULT_REL_RUNTIMEDIR "logs" -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 0 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_winnt.c b/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_winnt.c deleted file mode 100644 index 6fc0ae60..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_winnt.c +++ /dev/null @@ -1,1728 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef WIN32 - -#define CORE_PRIVATE -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "apr_portable.h" -#include "apr_thread_proc.h" -#include "apr_getopt.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_shm.h" -#include "apr_thread_mutex.h" -#include "ap_mpm.h" -#include "ap_config.h" -#include "ap_listen.h" -#include "mpm_default.h" -#include "mpm_winnt.h" -#include "mpm_common.h" -#include <malloc.h> -#include "apr_atomic.h" - - -/* scoreboard.c does the heavy lifting; all we do is create the child - * score by moving a handle down the pipe into the child's stdin. - */ -extern apr_shm_t *ap_scoreboard_shm; -server_rec *ap_server_conf; - -/* Definitions of WINNT MPM specific config globals */ -static HANDLE shutdown_event; /* used to signal the parent to shutdown */ -static HANDLE restart_event; /* used to signal the parent to restart */ - -static char ap_coredump_dir[MAX_STRING_LEN]; - -static int one_process = 0; -static char const* signal_arg = NULL; - -OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */ - -static DWORD parent_pid; -DWORD my_pid; - -int ap_threads_per_child = 0; -int use_acceptex = 1; -static int thread_limit = DEFAULT_THREAD_LIMIT; -static int first_thread_limit = 0; -static int changed_limit_at_restart; -int winnt_mpm_state = AP_MPMQ_STARTING; -/* ap_my_generation are used by the scoreboard code */ -ap_generation_t volatile ap_my_generation=0; - - -/* shared by service.c as global, although - * perhaps it should be private. - */ -apr_pool_t *pconf; - - -/* definitions from child.c */ -void child_main(apr_pool_t *pconf); - -/* used by parent to signal the child to start and exit - * NOTE: these are not sophisticated enough for multiple children - * so they ultimately should not be shared with child.c - */ -extern apr_proc_mutex_t *start_mutex; -extern HANDLE exit_event; - -/* Only one of these, the pipe from our parent, ment only for - * one child worker's consumption (not to be inherited!) - * XXX: decorate this name for the trunk branch, was left simplified - * only to make the 2.2 patch trivial to read. - */ -static HANDLE pipe; - -/* Stub functions until this MPM supports the connection status API */ - -AP_DECLARE(void) ap_update_connection_status(long conn_id, const char *key, \ - const char *value) -{ - /* NOP */ -} - -AP_DECLARE(void) ap_reset_connection_status(long conn_id) -{ - /* NOP */ -} - -AP_DECLARE(apr_array_header_t *) ap_get_status_table(apr_pool_t *p) -{ - /* NOP */ - return NULL; -} - -/* - * Command processors - */ - -static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_per_child = atoi(arg); - if (ap_threads_per_child > thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " - "value of %d threads,", ap_threads_per_child, - thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ThreadsPerChild to %d. To increase, please" - " see the", thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " ThreadLimit directive."); - ap_threads_per_child = thread_limit; - } - else if (ap_threads_per_child < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadsPerChild > 0, setting to 1"); - ap_threads_per_child = 1; - } - return NULL; -} -static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_thread_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_thread_limit = atoi(arg); - /* you cannot change ThreadLimit across a restart; ignore - * any such attempts - */ - if (first_thread_limit && - tmp_thread_limit != thread_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - thread_limit = tmp_thread_limit; - - if (thread_limit > MAX_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadLimit of %d exceeds compile time limit " - "of %d threads,", thread_limit, MAX_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); - thread_limit = MAX_THREAD_LIMIT; - } - else if (thread_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadLimit > 0, setting to 1"); - thread_limit = 1; - } - return NULL; -} -static const char *set_disable_acceptex(cmd_parms *cmd, void *dummy, char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - if (use_acceptex) { - use_acceptex = 0; - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, - "Disabled use of AcceptEx() WinSock2 API"); - } - return NULL; -} - -static const command_rec winnt_cmds[] = { -LISTEN_COMMANDS, -AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, - "Number of threads each child creates" ), -AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, - "Maximum worker threads in a server for this run of Apache"), -AP_INIT_NO_ARGS("Win32DisableAcceptEx", set_disable_acceptex, NULL, RSRC_CONF, - "Disable use of the high performance AcceptEx WinSock2 API to work around buggy VPN or Firewall software"), -{ NULL } -}; - - -/* - * Signalling Apache on NT. - * - * Under Unix, Apache can be told to shutdown or restart by sending various - * signals (HUP, USR, TERM). On NT we don't have easy access to signals, so - * we use "events" instead. The parent apache process goes into a loop - * where it waits forever for a set of events. Two of those events are - * called - * - * apPID_shutdown - * apPID_restart - * - * (where PID is the PID of the apache parent process). When one of these - * is signalled, the Apache parent performs the appropriate action. The events - * can become signalled through internal Apache methods (e.g. if the child - * finds a fatal error and needs to kill its parent), via the service - * control manager (the control thread will signal the shutdown event when - * requested to stop the Apache service), from the -k Apache command line, - * or from any external program which finds the Apache PID from the - * httpd.pid file. - * - * The signal_parent() function, below, is used to signal one of these events. - * It can be called by any child or parent process, since it does not - * rely on global variables. - * - * On entry, type gives the event to signal. 0 means shutdown, 1 means - * graceful restart. - */ -/* - * Initialise the signal names, in the global variables signal_name_prefix, - * signal_restart_name and signal_shutdown_name. - */ -#define MAX_SIGNAL_NAME 30 /* Long enough for apPID_shutdown, where PID is an int */ -char signal_name_prefix[MAX_SIGNAL_NAME]; -char signal_restart_name[MAX_SIGNAL_NAME]; -char signal_shutdown_name[MAX_SIGNAL_NAME]; -void setup_signal_names(char *prefix) -{ - apr_snprintf(signal_name_prefix, sizeof(signal_name_prefix), prefix); - apr_snprintf(signal_shutdown_name, sizeof(signal_shutdown_name), - "%s_shutdown", signal_name_prefix); - apr_snprintf(signal_restart_name, sizeof(signal_restart_name), - "%s_restart", signal_name_prefix); -} - -int volatile is_graceful = 0; - -AP_DECLARE(int) ap_graceful_stop_signalled(void) -{ - return is_graceful; -} - -AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type) -{ - HANDLE e; - char *signal_name; - - if (parent_pid == my_pid) { - switch(type) { - case SIGNAL_PARENT_SHUTDOWN: - { - SetEvent(shutdown_event); - break; - } - /* This MPM supports only graceful restarts right now */ - case SIGNAL_PARENT_RESTART: - case SIGNAL_PARENT_RESTART_GRACEFUL: - { - is_graceful = 1; - SetEvent(restart_event); - break; - } - } - return; - } - - switch(type) { - case SIGNAL_PARENT_SHUTDOWN: - { - signal_name = signal_shutdown_name; - break; - } - /* This MPM supports only graceful restarts right now */ - case SIGNAL_PARENT_RESTART: - case SIGNAL_PARENT_RESTART_GRACEFUL: - { - signal_name = signal_restart_name; - is_graceful = 1; - break; - } - default: - return; - } - - e = OpenEvent(EVENT_MODIFY_STATE, FALSE, signal_name); - if (!e) { - /* Um, problem, can't signal the parent, which means we can't - * signal ourselves to die. Ignore for now... - */ - ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), ap_server_conf, - "OpenEvent on %s event", signal_name); - return; - } - if (SetEvent(e) == 0) { - /* Same problem as above */ - ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), ap_server_conf, - "SetEvent on %s event", signal_name); - CloseHandle(e); - return; - } - CloseHandle(e); -} - - -/* - * Passed the following handles [in sync with send_handles_to_child()] - * - * ready event [signal the parent immediately, then close] - * exit event [save to poll later] - * start mutex [signal from the parent to begin accept()] - * scoreboard shm handle [to recreate the ap_scoreboard] - */ -void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, - apr_proc_mutex_t **child_start_mutex, - apr_shm_t **scoreboard_shm) -{ - HANDLE hScore; - HANDLE ready_event; - HANDLE os_start; - DWORD BytesRead; - void *sb_shared; - apr_status_t rv; - - /* *** We now do this was back in winnt_rewrite_args - * pipe = GetStdHandle(STD_INPUT_HANDLE); - */ - if (!ReadFile(pipe, &ready_event, sizeof(HANDLE), - &BytesRead, (LPOVERLAPPED) NULL) - || (BytesRead != sizeof(HANDLE))) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the ready event from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - - SetEvent(ready_event); - CloseHandle(ready_event); - - if (!ReadFile(pipe, child_exit_event, sizeof(HANDLE), - &BytesRead, (LPOVERLAPPED) NULL) - || (BytesRead != sizeof(HANDLE))) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the exit event from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - - if (!ReadFile(pipe, &os_start, sizeof(os_start), - &BytesRead, (LPOVERLAPPED) NULL) - || (BytesRead != sizeof(os_start))) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the start_mutex from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - *child_start_mutex = NULL; - if ((rv = apr_os_proc_mutex_put(child_start_mutex, &os_start, s->process->pool)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Child %d: Unable to access the start_mutex from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - - if (!ReadFile(pipe, &hScore, sizeof(hScore), - &BytesRead, (LPOVERLAPPED) NULL) - || (BytesRead != sizeof(hScore))) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the scoreboard from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - *scoreboard_shm = NULL; - if ((rv = apr_os_shm_put(scoreboard_shm, &hScore, s->process->pool)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Child %d: Unable to access the scoreboard from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - - rv = ap_reopen_scoreboard(s->process->pool, scoreboard_shm, 1); - if (rv || !(sb_shared = apr_shm_baseaddr_get(*scoreboard_shm))) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Child %d: Unable to reopen the scoreboard from the parent", my_pid); - exit(APEXIT_CHILDINIT); - } - /* We must 'initialize' the scoreboard to relink all the - * process-local pointer arrays into the shared memory block. - */ - ap_init_scoreboard(sb_shared); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Child %d: Retrieved our scoreboard from the parent.", my_pid); -} - - -static int send_handles_to_child(apr_pool_t *p, - HANDLE child_ready_event, - HANDLE child_exit_event, - apr_proc_mutex_t *child_start_mutex, - apr_shm_t *scoreboard_shm, - HANDLE hProcess, - apr_file_t *child_in) -{ - apr_status_t rv; - HANDLE hCurrentProcess = GetCurrentProcess(); - HANDLE hDup; - HANDLE os_start; - HANDLE hScore; - DWORD BytesWritten; - - if (!DuplicateHandle(hCurrentProcess, child_ready_event, hProcess, &hDup, - EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Unable to duplicate the ready event handle for the child"); - return -1; - } - if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to send the exit event handle to the child"); - return -1; - } - if (!DuplicateHandle(hCurrentProcess, child_exit_event, hProcess, &hDup, - EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Unable to duplicate the exit event handle for the child"); - return -1; - } - if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to send the exit event handle to the child"); - return -1; - } - if ((rv = apr_os_proc_mutex_get(&os_start, child_start_mutex)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to retrieve the start mutex for the child"); - return -1; - } - if (!DuplicateHandle(hCurrentProcess, os_start, hProcess, &hDup, - SYNCHRONIZE, FALSE, 0)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Unable to duplicate the start mutex to the child"); - return -1; - } - if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to send the start mutex to the child"); - return -1; - } - if ((rv = apr_os_shm_get(&hScore, scoreboard_shm)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to retrieve the scoreboard handle for the child"); - return -1; - } - if (!DuplicateHandle(hCurrentProcess, hScore, hProcess, &hDup, - FILE_MAP_READ | FILE_MAP_WRITE, FALSE, 0)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Unable to duplicate the scoreboard handle to the child"); - return -1; - } - if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to send the scoreboard handle to the child"); - return -1; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Parent: Sent the scoreboard to the child"); - return 0; -} - - -/* - * get_listeners_from_parent() - * The listen sockets are opened in the parent. This function, which runs - * exclusively in the child process, receives them from the parent and - * makes them availeble in the child. - */ -void get_listeners_from_parent(server_rec *s) -{ - WSAPROTOCOL_INFO WSAProtocolInfo; - ap_listen_rec *lr; - DWORD BytesRead; - int lcnt = 0; - SOCKET nsd; - - /* Set up a default listener if necessary */ - if (ap_listeners == NULL) { - ap_listen_rec *lr; - lr = apr_palloc(s->process->pool, sizeof(ap_listen_rec)); - lr->sd = NULL; - lr->next = ap_listeners; - ap_listeners = lr; - } - - /* Open the pipe to the parent process to receive the inherited socket - * data. The sockets have been set to listening in the parent process. - * - * *** We now do this was back in winnt_rewrite_args - * pipe = GetStdHandle(STD_INPUT_HANDLE); - */ - for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) { - if (!ReadFile(pipe, &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO), - &BytesRead, (LPOVERLAPPED) NULL)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "setup_inherited_listeners: Unable to read socket data from parent"); - exit(APEXIT_CHILDINIT); - } - nsd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, - &WSAProtocolInfo, 0, 0); - if (nsd == INVALID_SOCKET) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, - "Child %d: setup_inherited_listeners(), WSASocket failed to open the inherited socket.", my_pid); - exit(APEXIT_CHILDINIT); - } - - if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - HANDLE hProcess = GetCurrentProcess(); - HANDLE dup; - if (DuplicateHandle(hProcess, (HANDLE) nsd, hProcess, &dup, - 0, FALSE, DUPLICATE_SAME_ACCESS)) { - closesocket(nsd); - nsd = (SOCKET) dup; - } - } - else { - /* A different approach. Many users report errors such as - * (32538)An operation was attempted on something that is not - * a socket. : Parent: WSADuplicateSocket failed... - * - * This appears that the duplicated handle is no longer recognized - * as a socket handle. SetHandleInformation should overcome that - * problem by not altering the handle identifier. But this won't - * work on 9x - it's unsupported. - */ - if (!SetHandleInformation((HANDLE)nsd, HANDLE_FLAG_INHERIT, 0)) { - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), ap_server_conf, - "set_listeners_noninheritable: SetHandleInformation failed."); - } - } - apr_os_sock_put(&lr->sd, &nsd, s->process->pool); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Child %d: retrieved %d listeners from parent", my_pid, lcnt); -} - - -static int send_listeners_to_child(apr_pool_t *p, DWORD dwProcessId, - apr_file_t *child_in) -{ - apr_status_t rv; - int lcnt = 0; - ap_listen_rec *lr; - LPWSAPROTOCOL_INFO lpWSAProtocolInfo; - DWORD BytesWritten; - - /* Run the chain of open sockets. For each socket, duplicate it - * for the target process then send the WSAPROTOCOL_INFO - * (returned by dup socket) to the child. - */ - for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) { - int nsd; - lpWSAProtocolInfo = apr_pcalloc(p, sizeof(WSAPROTOCOL_INFO)); - apr_os_sock_get(&nsd,lr->sd); - ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, - "Parent: Duplicating socket %d and sending it to child process %d", - nsd, dwProcessId); - if (WSADuplicateSocket(nsd, dwProcessId, - lpWSAProtocolInfo) == SOCKET_ERROR) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, - "Parent: WSADuplicateSocket failed for socket %d. Check the FAQ.", lr->sd ); - return -1; - } - - if ((rv = apr_file_write_full(child_in, lpWSAProtocolInfo, - sizeof(WSAPROTOCOL_INFO), &BytesWritten)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to write duplicated socket %d to the child.", lr->sd ); - return -1; - } - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Parent: Sent %d listeners to child %d", lcnt, dwProcessId); - return 0; -} - -enum waitlist_e { - waitlist_ready = 0, - waitlist_term = 1 -}; - -static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_event, - DWORD *child_pid) -{ - /* These NEVER change for the lifetime of this parent - */ - static char **args = NULL; - static char pidbuf[28]; - - apr_status_t rv; - apr_pool_t *ptemp; - apr_procattr_t *attr; - apr_proc_t new_child; - apr_file_t *child_out, *child_err; - HANDLE hExitEvent; - HANDLE waitlist[2]; /* see waitlist_e */ - char *cmd; - char *cwd; - char **env; - int envc; - - apr_pool_sub_make(&ptemp, p, NULL); - - /* Build the command line. Should look something like this: - * C:/apache/bin/apache.exe -f ap_server_confname - * First, get the path to the executable... - */ - apr_procattr_create(&attr, ptemp); - apr_procattr_cmdtype_set(attr, APR_PROGRAM); - apr_procattr_detach_set(attr, 1); - if (((rv = apr_filepath_get(&cwd, 0, ptemp)) != APR_SUCCESS) - || ((rv = apr_procattr_dir_set(attr, cwd)) != APR_SUCCESS)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Failed to get the current path"); - } - - if (!args) { - /* Build the args array, only once since it won't change - * for the lifetime of this parent process. - */ - if ((rv = ap_os_proc_filepath(&cmd, ptemp)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, ERROR_BAD_PATHNAME, ap_server_conf, - "Parent: Failed to get full path of %s", - ap_server_conf->process->argv[0]); - apr_pool_destroy(ptemp); - return -1; - } - - args = malloc((ap_server_conf->process->argc + 1) * sizeof (char*)); - memcpy(args + 1, ap_server_conf->process->argv + 1, - (ap_server_conf->process->argc - 1) * sizeof (char*)); - args[0] = malloc(strlen(cmd) + 1); - strcpy(args[0], cmd); - args[ap_server_conf->process->argc] = NULL; - } - else { - cmd = args[0]; - } - - /* Create a pipe to send handles to the child */ - if ((rv = apr_procattr_io_set(attr, APR_FULL_BLOCK, - APR_NO_PIPE, APR_NO_PIPE)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to create child stdin pipe."); - apr_pool_destroy(ptemp); - return -1; - } - - /* httpd-2.0/2.2 specific to work around apr_proc_create bugs */ - /* set "NUL" as sysout for the child */ - if (((rv = apr_file_open(&child_out, "NUL", APR_WRITE | APR_READ, APR_OS_DEFAULT,p)) - != APR_SUCCESS) || - ((rv = apr_procattr_child_out_set(attr, child_out, NULL)) - != APR_SUCCESS)) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, - "Parent: Could not set child process stdout"); - } - if (((rv = apr_file_open_stderr(&child_err, p)) - != APR_SUCCESS) || - ((rv = apr_procattr_child_err_set(attr, child_err, NULL)) - != APR_SUCCESS)) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, - "Parent: Could not set child process stderr"); - } - - /* Create the child_ready_event */ - waitlist[waitlist_ready] = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!waitlist[waitlist_ready]) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Could not create ready event for child process"); - apr_pool_destroy (ptemp); - return -1; - } - - /* Create the child_exit_event */ - hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!hExitEvent) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Could not create exit event for child process"); - apr_pool_destroy(ptemp); - CloseHandle(waitlist[waitlist_ready]); - return -1; - } - - /* Build the env array */ - for (envc = 0; _environ[envc]; ++envc) { - ; - } - env = apr_palloc(ptemp, (envc + 2) * sizeof (char*)); - memcpy(env, _environ, envc * sizeof (char*)); - apr_snprintf(pidbuf, sizeof(pidbuf), "AP_PARENT_PID=%i", parent_pid); - env[envc] = pidbuf; - env[envc + 1] = NULL; - - rv = apr_proc_create(&new_child, cmd, args, env, attr, ptemp); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Failed to create the child process."); - apr_pool_destroy(ptemp); - CloseHandle(hExitEvent); - CloseHandle(waitlist[waitlist_ready]); - CloseHandle(new_child.hproc); - return -1; - } - apr_file_close(child_out); - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Parent: Created child process %d", new_child.pid); - - if (send_handles_to_child(ptemp, waitlist[waitlist_ready], hExitEvent, - start_mutex, ap_scoreboard_shm, - new_child.hproc, new_child.in)) { - /* - * This error is fatal, mop up the child and move on - * We toggle the child's exit event to cause this child - * to quit even as it is attempting to start. - */ - SetEvent(hExitEvent); - apr_pool_destroy(ptemp); - CloseHandle(hExitEvent); - CloseHandle(waitlist[waitlist_ready]); - CloseHandle(new_child.hproc); - return -1; - } - - /* Important: - * Give the child process a chance to run before dup'ing the sockets. - * We have already set the listening sockets noninheritable, but if - * WSADuplicateSocket runs before the child process initializes - * the listeners will be inherited anyway. - */ - waitlist[waitlist_term] = new_child.hproc; - rv = WaitForMultipleObjects(2, waitlist, FALSE, INFINITE); - CloseHandle(waitlist[waitlist_ready]); - if (rv != WAIT_OBJECT_0) { - /* - * Outch... that isn't a ready signal. It's dead, Jim! - */ - SetEvent(hExitEvent); - apr_pool_destroy(ptemp); - CloseHandle(hExitEvent); - CloseHandle(new_child.hproc); - return -1; - } - - if (send_listeners_to_child(ptemp, new_child.pid, new_child.in)) { - /* - * This error is fatal, mop up the child and move on - * We toggle the child's exit event to cause this child - * to quit even as it is attempting to start. - */ - SetEvent(hExitEvent); - apr_pool_destroy(ptemp); - CloseHandle(hExitEvent); - CloseHandle(new_child.hproc); - return -1; - } - - apr_file_close(new_child.in); - - *child_exit_event = hExitEvent; - *child_proc = new_child.hproc; - *child_pid = new_child.pid; - - return 0; -} - -/*********************************************************************** - * master_main() - * master_main() runs in the parent process. It creates the child - * process which handles HTTP requests then waits on one of three - * events: - * - * restart_event - * ------------- - * The restart event causes master_main to start a new child process and - * tells the old child process to exit (by setting the child_exit_event). - * The restart event is set as a result of one of the following: - * 1. An apache -k restart command on the command line - * 2. A command received from Windows service manager which gets - * translated into an ap_signal_parent(SIGNAL_PARENT_RESTART) - * call by code in service.c. - * 3. The child process calling ap_signal_parent(SIGNAL_PARENT_RESTART) - * as a result of hitting MaxRequestsPerChild. - * - * shutdown_event - * -------------- - * The shutdown event causes master_main to tell the child process to - * exit and that the server is shutting down. The shutdown event is - * set as a result of one of the following: - * 1. An apache -k shutdown command on the command line - * 2. A command received from Windows service manager which gets - * translated into an ap_signal_parent(SIGNAL_PARENT_SHUTDOWN) - * call by code in service.c. - * - * child process handle - * -------------------- - * The child process handle will be signaled if the child process - * exits for any reason. In a normal running server, the signaling - * of this event means that the child process has exited prematurely - * due to a seg fault or other irrecoverable error. For server - * robustness, master_main will restart the child process under this - * condtion. - * - * master_main uses the child_exit_event to signal the child process - * to exit. - **********************************************************************/ -#define NUM_WAIT_HANDLES 3 -#define CHILD_HANDLE 0 -#define SHUTDOWN_HANDLE 1 -#define RESTART_HANDLE 2 -static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_event) -{ - int rv, cld; - int restart_pending; - int shutdown_pending; - HANDLE child_exit_event; - HANDLE event_handles[NUM_WAIT_HANDLES]; - DWORD child_pid; - - restart_pending = shutdown_pending = 0; - - event_handles[SHUTDOWN_HANDLE] = shutdown_event; - event_handles[RESTART_HANDLE] = restart_event; - - /* Create a single child process */ - rv = create_process(pconf, &event_handles[CHILD_HANDLE], - &child_exit_event, &child_pid); - if (rv < 0) - { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "master_main: create child process failed. Exiting."); - shutdown_pending = 1; - goto die_now; - } - if (!strcasecmp(signal_arg, "runservice")) { - mpm_service_started(); - } - - /* Update the scoreboard. Note that there is only a single active - * child at once. - */ - ap_scoreboard_image->parent[0].quiescing = 0; - ap_scoreboard_image->parent[0].pid = child_pid; - - /* Wait for shutdown or restart events or for child death */ - winnt_mpm_state = AP_MPMQ_RUNNING; - rv = WaitForMultipleObjects(NUM_WAIT_HANDLES, (HANDLE *) event_handles, FALSE, INFINITE); - cld = rv - WAIT_OBJECT_0; - if (rv == WAIT_FAILED) { - /* Something serious is wrong */ - ap_log_error(APLOG_MARK,APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "master_main: WaitForMultipeObjects WAIT_FAILED -- doing server shutdown"); - shutdown_pending = 1; - } - else if (rv == WAIT_TIMEOUT) { - /* Hey, this cannot happen */ - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, - "master_main: WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT"); - shutdown_pending = 1; - } - else if (cld == SHUTDOWN_HANDLE) { - /* shutdown_event signalled */ - shutdown_pending = 1; - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, s, - "Parent: Received shutdown signal -- Shutting down the server."); - if (ResetEvent(shutdown_event) == 0) { - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, - "ResetEvent(shutdown_event)"); - } - } - else if (cld == RESTART_HANDLE) { - /* Received a restart event. Prepare the restart_event to be reused - * then signal the child process to exit. - */ - restart_pending = 1; - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "Parent: Received restart signal -- Restarting the server."); - if (ResetEvent(restart_event) == 0) { - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, - "Parent: ResetEvent(restart_event) failed."); - } - if (SetEvent(child_exit_event) == 0) { - ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, - "Parent: SetEvent for child process %d failed.", - event_handles[CHILD_HANDLE]); - } - /* Don't wait to verify that the child process really exits, - * just move on with the restart. - */ - CloseHandle(event_handles[CHILD_HANDLE]); - event_handles[CHILD_HANDLE] = NULL; - } - else { - /* The child process exited prematurely due to a fatal error. */ - DWORD exitcode; - if (!GetExitCodeProcess(event_handles[CHILD_HANDLE], &exitcode)) { - /* HUH? We did exit, didn't we? */ - exitcode = APEXIT_CHILDFATAL; - } - if ( exitcode == APEXIT_CHILDFATAL - || exitcode == APEXIT_CHILDINIT - || exitcode == APEXIT_INIT) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, - "Parent: child process exited with status %u -- Aborting.", exitcode); - } - else { - int i; - restart_pending = 1; - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Parent: child process exited with status %u -- Restarting.", exitcode); - for (i = 0; i < ap_threads_per_child; i++) { - ap_update_child_status_from_indexes(0, i, SERVER_DEAD, NULL); - } - } - CloseHandle(event_handles[CHILD_HANDLE]); - event_handles[CHILD_HANDLE] = NULL; - } - if (restart_pending) { - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - } -die_now: - if (shutdown_pending) - { - int timeout = 30000; /* Timeout is milliseconds */ - winnt_mpm_state = AP_MPMQ_STOPPING; - - /* This shutdown is only marginally graceful. We will give the - * child a bit of time to exit gracefully. If the time expires, - * the child will be wacked. - */ - if (!strcasecmp(signal_arg, "runservice")) { - mpm_service_stopping(); - } - /* Signal the child processes to exit */ - if (SetEvent(child_exit_event) == 0) { - ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), ap_server_conf, - "Parent: SetEvent for child process %d failed", event_handles[CHILD_HANDLE]); - } - if (event_handles[CHILD_HANDLE]) { - rv = WaitForSingleObject(event_handles[CHILD_HANDLE], timeout); - if (rv == WAIT_OBJECT_0) { - ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Parent: Child process exited successfully."); - CloseHandle(event_handles[CHILD_HANDLE]); - event_handles[CHILD_HANDLE] = NULL; - } - else { - ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Parent: Forcing termination of child process %d ", event_handles[CHILD_HANDLE]); - TerminateProcess(event_handles[CHILD_HANDLE], 1); - CloseHandle(event_handles[CHILD_HANDLE]); - event_handles[CHILD_HANDLE] = NULL; - } - } - CloseHandle(child_exit_event); - return 0; /* Tell the caller we do not want to restart */ - } - winnt_mpm_state = AP_MPMQ_STARTING; - CloseHandle(child_exit_event); - return 1; /* Tell the caller we want a restart */ -} - -/* service_nt_main_fn needs to append the StartService() args - * outside of our call stack and thread as the service starts... - */ -apr_array_header_t *mpm_new_argv; - -/* Remember service_to_start failures to log and fail in pre_config. - * Remember inst_argc and inst_argv for installing or starting the - * service after we preflight the config. - */ - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = MAXIMUM_WAIT_OBJECTS; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_STATIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = HARD_SERVER_LIMIT; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = thread_limit; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = ap_threads_per_child; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = winnt_mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -#define SERVICE_UNSET (-1) -static apr_status_t service_set = SERVICE_UNSET; -static apr_status_t service_to_start_success; -static int inst_argc; -static const char * const *inst_argv; -static char *service_name = NULL; - -void winnt_rewrite_args(process_rec *process) -{ - /* Handle the following SCM aspects in this phase: - * - * -k runservice [transition for WinNT, nothing for Win9x] - * -k (!)install [error out if name is not installed] - * -k uninstall - * -k stop - * -k shutdown (same as -k stop). Maintained for backward compatability. - * - * We can't leave this phase until we know our identity - * and modify the command arguments appropriately. - * - * We do not care if the .conf file exists or is parsable when - * attempting to stop or uninstall a service. - */ - apr_status_t rv; - char *def_server_root; - char *binpath; - char optbuf[3]; - const char *optarg; - int fixed_args; - char *pid; - apr_getopt_t *opt; - int running_as_service = 1; - int errout = 0; - - pconf = process->pconf; - - osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osver); - - /* AP_PARENT_PID is only valid in the child */ - pid = getenv("AP_PARENT_PID"); - if (pid) - { - HANDLE filehand; - HANDLE hproc = GetCurrentProcess(); - - /* This is the child */ - my_pid = GetCurrentProcessId(); - parent_pid = (DWORD) atol(pid); - - /* Prevent holding open the (nonexistant) console */ - real_exit_code = 0; - - /* The parent gave us stdin, we need to remember this - * handle, and no longer inherit it at our children - * (we can't slurp it up now, we just aren't ready yet). - * The original handle is closed below, at apr_file_dup2() - */ - pipe = GetStdHandle(STD_INPUT_HANDLE); - if (DuplicateHandle(hproc, pipe, - hproc, &filehand, 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - pipe = filehand; - } - - /* The parent gave us stdout of the NUL device, - * and expects us to suck up stdin of all of our - * shared handles and data from the parent. - * Don't infect child processes with our stdin - * handle, use another handle to NUL! - */ - { - apr_file_t *infile, *outfile; - if ((apr_file_open_stdout(&outfile, process->pool) == APR_SUCCESS) - && (apr_file_open_stdin(&infile, process->pool) == APR_SUCCESS)) - apr_file_dup2(infile, outfile, process->pool); - } - - /* This child needs the existing stderr opened for logging, - * already - */ - - /* The parent is responsible for providing the - * COMPLETE ARGUMENTS REQUIRED to the child. - * - * No further argument parsing is needed, but - * for good measure we will provide a simple - * signal string for later testing. - */ - signal_arg = "runchild"; - return; - } - - /* This is the parent, we have a long way to go :-) */ - parent_pid = my_pid = GetCurrentProcessId(); - - /* This behavior is voided by setting real_exit_code to 0 */ - atexit(hold_console_open_on_error); - - /* Rewrite process->argv[]; - * - * strip out -k signal into signal_arg - * strip out -n servicename and set the names - * add default -d serverroot from the path of this executable - * - * The end result will look like: - * - * The invocation command (%0) - * The -d serverroot default from the running executable - * The requested service's (-n) registry ConfigArgs - * The WinNT SCM's StartService() args - */ - if ((rv = ap_os_proc_filepath(&binpath, process->pconf)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_CRIT, rv, NULL, - "Failed to get the full path of %s", process->argv[0]); - exit(APEXIT_INIT); - } - /* WARNING: There is an implict assumption here that the - * executable resides in ServerRoot or ServerRoot\bin - */ - def_server_root = (char *) apr_filename_of_pathname(binpath); - if (def_server_root > binpath) { - *(def_server_root - 1) = '\0'; - def_server_root = (char *) apr_filename_of_pathname(binpath); - if (!strcasecmp(def_server_root, "bin")) - *(def_server_root - 1) = '\0'; - } - apr_filepath_merge(&def_server_root, NULL, binpath, - APR_FILEPATH_TRUENAME, process->pool); - - /* Use process->pool so that the rewritten argv - * lasts for the lifetime of the server process, - * because pconf will be destroyed after the - * initial pre-flight of the config parser. - */ - mpm_new_argv = apr_array_make(process->pool, process->argc + 2, - sizeof(const char *)); - *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; - *(const char **)apr_array_push(mpm_new_argv) = "-d"; - *(const char **)apr_array_push(mpm_new_argv) = def_server_root; - - fixed_args = mpm_new_argv->nelts; - - optbuf[0] = '-'; - optbuf[2] = '\0'; - apr_getopt_init(&opt, process->pool, process->argc, (char**) process->argv); - opt->errfn = NULL; - while ((rv = apr_getopt(opt, "wn:k:" AP_SERVER_BASEARGS, - optbuf + 1, &optarg)) == APR_SUCCESS) { - switch (optbuf[1]) { - - /* Shortcuts; include the -w option to hold the window open on error. - * This must not be toggled once we reset real_exit_code to 0! - */ - case 'w': - if (real_exit_code) - real_exit_code = 2; - break; - - case 'n': - service_set = mpm_service_set_name(process->pool, &service_name, - optarg); - break; - - case 'k': - signal_arg = optarg; - break; - - case 'E': - errout = 1; - /* Fall through so the Apache main() handles the 'E' arg */ - default: - *(const char **)apr_array_push(mpm_new_argv) = - apr_pstrdup(process->pool, optbuf); - - if (optarg) { - *(const char **)apr_array_push(mpm_new_argv) = optarg; - } - break; - } - } - - /* back up to capture the bad argument */ - if (rv == APR_BADCH || rv == APR_BADARG) { - opt->ind--; - } - - while (opt->ind < opt->argc) { - *(const char **)apr_array_push(mpm_new_argv) = - apr_pstrdup(process->pool, opt->argv[opt->ind++]); - } - - /* Track the number of args actually entered by the user */ - inst_argc = mpm_new_argv->nelts - fixed_args; - - /* Provide a default 'run' -k arg to simplify signal_arg tests */ - if (!signal_arg) - { - signal_arg = "run"; - running_as_service = 0; - } - - if (!strcasecmp(signal_arg, "runservice")) - { - /* Start the NT Service _NOW_ because the WinNT SCM is - * expecting us to rapidly assume control of our own - * process, the SCM will tell us our service name, and - * may have extra StartService() command arguments to - * add for us. - * - * The SCM will generally invoke the executable with - * the c:\win\system32 default directory. This is very - * lethal if folks use ServerRoot /foopath on windows - * without a drive letter. Change to the default root - * (path to apache root, above /bin) for safety. - */ - apr_filepath_set(def_server_root, process->pool); - - /* Any other process has a console, so we don't to begin - * a Win9x service until the configuration is parsed and - * any command line errors are reported. - * - * We hold the return value so that we can die in pre_config - * after logging begins, and the failure can land in the log. - */ - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - apr_file_t *nullfile; - - if (!errout) { - mpm_nt_eventlog_stderr_open(service_name, process->pool); - } - service_to_start_success = mpm_service_to_start(&service_name, - process->pool); - if (service_to_start_success == APR_SUCCESS) { - service_set = APR_SUCCESS; - } - - /* Open a null handle to soak stdout in this process. - * Windows service processes are missing any file handle - * usable for stdin/out/err. This was the cause of later - * trouble with invocations of apr_file_open_stdout() - */ - if ((rv = apr_file_open(&nullfile, "NUL", - APR_READ | APR_WRITE, APR_OS_DEFAULT, - process->pool)) == APR_SUCCESS) { - apr_file_t *nullstdout; - if (apr_file_open_stdout(&nullstdout, process->pool) - == APR_SUCCESS) - apr_file_dup2(nullstdout, nullfile, process->pool); - apr_file_close(nullfile); - } - } - } - - /* Get the default for any -k option, except run */ - if (service_set == SERVICE_UNSET && strcasecmp(signal_arg, "run")) { - service_set = mpm_service_set_name(process->pool, &service_name, - AP_DEFAULT_SERVICE_NAME); - } - - if (!strcasecmp(signal_arg, "install")) /* -k install */ - { - if (service_set == APR_SUCCESS) - { - ap_log_error(APLOG_MARK,APLOG_ERR, 0, NULL, - "%s: Service is already installed.", service_name); - exit(APEXIT_INIT); - } - } - else if (running_as_service) - { - if (service_set == APR_SUCCESS) - { - /* Attempt to Uninstall, or stop, before - * we can read the arguments or .conf files - */ - if (!strcasecmp(signal_arg, "uninstall")) { - rv = mpm_service_uninstall(); - exit(rv); - } - - if ((!strcasecmp(signal_arg, "stop")) || - (!strcasecmp(signal_arg, "shutdown"))) { - mpm_signal_service(process->pool, 0); - exit(0); - } - - rv = mpm_merge_service_args(process->pool, mpm_new_argv, - fixed_args); - if (rv == APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_INFO, 0, NULL, - "Using ConfigArgs of the installed service " - "\"%s\".", service_name); - } - else { - ap_log_error(APLOG_MARK,APLOG_WARNING, rv, NULL, - "No installed ConfigArgs for the service " - "\"%s\", using Apache defaults.", service_name); - } - } - else - { - ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL, - "No installed service named \"%s\".", service_name); - exit(APEXIT_INIT); - } - } - if (strcasecmp(signal_arg, "install") && service_set && service_set != SERVICE_UNSET) - { - ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL, - "No installed service named \"%s\".", service_name); - exit(APEXIT_INIT); - } - - /* Track the args actually entered by the user. - * These will be used for the -k install parameters, as well as - * for the -k start service override arguments. - */ - inst_argv = (const char * const *)mpm_new_argv->elts - + mpm_new_argv->nelts - inst_argc; - - process->argc = mpm_new_argv->nelts; - process->argv = (const char * const *) mpm_new_argv->elts; -} - - -static int winnt_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *ptemp) -{ - /* Handle the following SCM aspects in this phase: - * - * -k runservice [WinNT errors logged from rewrite_args] - */ - - /* Initialize shared static objects. - */ - pconf = pconf_; - - if (ap_exists_config_define("ONE_PROCESS") || - ap_exists_config_define("DEBUG")) - one_process = -1; - - if (!strcasecmp(signal_arg, "runservice") - && (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - && (service_to_start_success != APR_SUCCESS)) { - ap_log_error(APLOG_MARK,APLOG_CRIT, service_to_start_success, NULL, - "%s: Unable to start the service manager.", - service_name); - exit(APEXIT_INIT); - } - - /* Win9x: disable AcceptEx */ - if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - use_acceptex = 0; - } - - ap_listen_pre_config(); - ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; - ap_pid_fname = DEFAULT_PIDLOG; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - return OK; -} - -static int winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec* s) -{ - static int restart_num = 0; - apr_status_t rv = 0; - - /* Handle the following SCM aspects in this phase: - * - * -k install - * -k config - * -k start - * -k restart - * -k runservice [Win95, only once - after we parsed the config] - * - * because all of these signals are useful _only_ if there - * is a valid conf\httpd.conf environment to start. - * - * We reached this phase by avoiding errors that would cause - * these options to fail unexpectedly in another process. - */ - - if (!strcasecmp(signal_arg, "install")) { - rv = mpm_service_install(ptemp, inst_argc, inst_argv, 0); - apr_pool_destroy(s->process->pool); - apr_terminate(); - exit(rv); - } - if (!strcasecmp(signal_arg, "config")) { - rv = mpm_service_install(ptemp, inst_argc, inst_argv, 1); - apr_pool_destroy(s->process->pool); - apr_terminate(); - exit(rv); - } - - if (!strcasecmp(signal_arg, "start")) { - ap_listen_rec *lr; - - /* Close the listening sockets. */ - for (lr = ap_listeners; lr; lr = lr->next) { - apr_socket_close(lr->sd); - lr->active = 0; - } - rv = mpm_service_start(ptemp, inst_argc, inst_argv); - apr_pool_destroy(s->process->pool); - apr_terminate(); - exit(rv); - } - - if (!strcasecmp(signal_arg, "restart")) { - mpm_signal_service(ptemp, 1); - apr_pool_destroy(s->process->pool); - apr_terminate(); - exit(rv); - } - - if (parent_pid == my_pid) - { - if (restart_num++ == 1) - { - /* This code should be run once in the parent and not run - * across a restart - */ - PSECURITY_ATTRIBUTES sa = GetNullACL(); /* returns NULL if invalid (Win95?) */ - setup_signal_names(apr_psprintf(pconf,"ap%d", parent_pid)); - - ap_log_pid(pconf, ap_pid_fname); - - /* Create shutdown event, apPID_shutdown, where PID is the parent - * Apache process ID. Shutdown is signaled by 'apache -k shutdown'. - */ - shutdown_event = CreateEvent(sa, FALSE, FALSE, signal_shutdown_name); - if (!shutdown_event) { - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Cannot create shutdown event %s", signal_shutdown_name); - CleanNullACL((void *)sa); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* Create restart event, apPID_restart, where PID is the parent - * Apache process ID. Restart is signaled by 'apache -k restart'. - */ - restart_event = CreateEvent(sa, FALSE, FALSE, signal_restart_name); - if (!restart_event) { - CloseHandle(shutdown_event); - ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Parent: Cannot create restart event %s", signal_restart_name); - CleanNullACL((void *)sa); - return HTTP_INTERNAL_SERVER_ERROR; - } - CleanNullACL((void *)sa); - - /* Now that we are flying at 15000 feet... - * wipe out the Win95 service console, - * signal the SCM the WinNT service started, or - * if not a service, setup console handlers instead. - */ - if (!strcasecmp(signal_arg, "runservice")) - { - if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT) - { - rv = mpm_service_to_start(&service_name, - s->process->pool); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "%s: Unable to start the service manager.", - service_name); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - } - - /* Create the start mutex, as an unnamed object for security. - * Ths start mutex is used during a restart to prevent more than - * one child process from entering the accept loop at once. - */ - rv = apr_proc_mutex_create(&start_mutex, NULL, - APR_LOCK_DEFAULT, - ap_server_conf->process->pool); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "%s: Unable to create the start_mutex.", - service_name); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - /* Always reset our console handler to be the first, even on a restart - * because some modules (e.g. mod_perl) might have set a console - * handler to terminate the process. - */ - if (strcasecmp(signal_arg, "runservice")) - mpm_start_console_handler(); - } - else /* parent_pid != my_pid */ - { - mpm_start_child_console_handler(); - } - return OK; -} - -/* This really should be a post_config hook, but the error log is already - * redirected by that point, so we need to do this in the open_logs phase. - */ -static int winnt_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - /* Initialize shared static objects. - */ - ap_server_conf = s; - - if (parent_pid != my_pid) { - return OK; - } - - /* We cannot initialize our listeners if we are restarting - * (the parent process already has glomed on to them) - * nor should we do so for service reconfiguration - * (since the service may already be running.) - */ - if (!strcasecmp(signal_arg, "restart") - || !strcasecmp(signal_arg, "config")) { - return OK; - } - - if (ap_setup_listeners(s) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, - NULL, "no listening sockets available, shutting down"); - return DONE; - } - - return OK; -} - -static void winnt_child_init(apr_pool_t *pchild, struct server_rec *s) -{ - apr_status_t rv; - - setup_signal_names(apr_psprintf(pchild,"ap%d", parent_pid)); - - /* This is a child process, not in single process mode */ - if (!one_process) { - /* Set up events and the scoreboard */ - get_handles_from_parent(s, &exit_event, &start_mutex, - &ap_scoreboard_shm); - - /* Set up the listeners */ - get_listeners_from_parent(s); - - /* Done reading from the parent, close that channel */ - CloseHandle(pipe); - - ap_my_generation = ap_scoreboard_image->global->running_generation; - } - else { - /* Single process mode - this lock doesn't even need to exist */ - rv = apr_proc_mutex_create(&start_mutex, signal_name_prefix, - APR_LOCK_DEFAULT, s->process->pool); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "%s child %d: Unable to init the start_mutex.", - service_name, my_pid); - exit(APEXIT_CHILDINIT); - } - - /* Borrow the shutdown_even as our _child_ loop exit event */ - exit_event = shutdown_event; - } -} - - -AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) -{ - static int restart = 0; /* Default is "not a restart" */ - - if (!restart) { - first_thread_limit = thread_limit; - } - - if (changed_limit_at_restart) { - ap_log_error(APLOG_MARK, APLOG_WARNING, APR_SUCCESS, ap_server_conf, - "WARNING: Attempt to change ThreadLimit ignored " - "during restart"); - changed_limit_at_restart = 0; - } - - /* ### If non-graceful restarts are ever introduced - we need to rerun - * the pre_mpm hook on subsequent non-graceful restarts. But Win32 - * has only graceful style restarts - and we need this hook to act - * the same on Win32 as on Unix. - */ - if (!restart && ((parent_pid == my_pid) || one_process)) { - /* Set up the scoreboard. */ - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - return 1; - } - } - - if ((parent_pid != my_pid) || one_process) - { - /* The child process or in one_process (debug) mode - */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Child process is running", my_pid); - - child_main(pconf); - - ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Child process is exiting", my_pid); - return 1; - } - else - { - /* A real-honest to goodness parent */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); - - restart = master_main(ap_server_conf, shutdown_event, restart_event); - - if (!restart) - { - /* Shutting down. Clean up... */ - const char *pidfile = ap_server_root_relative (pconf, ap_pid_fname); - - if (pidfile != NULL && unlink(pidfile) == 0) { - ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, - ap_server_conf, "removed PID file %s (pid=%ld)", - pidfile, GetCurrentProcessId()); - } - apr_proc_mutex_destroy(start_mutex); - - CloseHandle(restart_event); - CloseHandle(shutdown_event); - - return 1; - } - } - - return 0; /* Restart */ -} - -static void winnt_hooks(apr_pool_t *p) -{ - /* The prefork open_logs phase must run before the core's, or stderr - * will be redirected to a file, and the messages won't print to the - * console. - */ - static const char *const aszSucc[] = {"core.c", NULL}; - - ap_hook_pre_config(winnt_pre_config, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_post_config(winnt_post_config, NULL, NULL, 0); - ap_hook_child_init(winnt_child_init, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_open_logs(winnt_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); -} - -AP_MODULE_DECLARE_DATA module mpm_winnt_module = { - MPM20_MODULE_STUFF, - winnt_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - winnt_cmds, /* command apr_table_t */ - winnt_hooks /* register_hooks */ -}; - -#endif /* def WIN32 */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_winnt.h b/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_winnt.h deleted file mode 100644 index 8eb04303..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/mpm_winnt.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_WINNT_H -#define APACHE_MPM_WINNT_H - -#include "ap_listen.h" - -/* From service.c: */ - -#define SERVICE_APACHE_RESTART 128 - -#ifndef AP_DEFAULT_SERVICE_NAME -#define AP_DEFAULT_SERVICE_NAME "Apache2" -#endif - -#define SERVICECONFIG9X "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices" -#define SERVICECONFIG "System\\CurrentControlSet\\Services\\%s" -#define SERVICEPARAMS "System\\CurrentControlSet\\Services\\%s\\Parameters" - -apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, - const char *set_name); -apr_status_t mpm_merge_service_args(apr_pool_t *p, apr_array_header_t *args, - int fixed_args); - -apr_status_t mpm_service_to_start(const char **display_name, apr_pool_t *p); -apr_status_t mpm_service_started(void); -apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, - char const* const* argv, int reconfig); -apr_status_t mpm_service_uninstall(void); - -apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, - char const* const* argv); - -void mpm_signal_service(apr_pool_t *ptemp, int signal); - -void mpm_service_stopping(void); - -void mpm_start_console_handler(void); -void mpm_start_child_console_handler(void); - -/* From nt_eventlog.c: */ - -void mpm_nt_eventlog_stderr_open(char *display_name, apr_pool_t *p); -void mpm_nt_eventlog_stderr_flush(void); - -/* From winnt.c: */ -extern int use_acceptex; -extern int winnt_mpm_state; -extern OSVERSIONINFO osver; -extern void clean_child_exit(int); - -void setup_signal_names(char *prefix); - -typedef enum { - SIGNAL_PARENT_SHUTDOWN, - SIGNAL_PARENT_RESTART, - SIGNAL_PARENT_RESTART_GRACEFUL -} ap_signal_parent_e; -AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type); - -/* - * The Windoes MPM uses a queue of completion contexts that it passes - * between the accept threads and the worker threads. Declare the - * functions to access the queue and the structures passed on the - * queue in the header file to enable modules to access them - * if necessary. The queue resides in the MPM. - */ -#ifdef CONTAINING_RECORD -#undef CONTAINING_RECORD -#endif -#define CONTAINING_RECORD(address, type, field) ((type *)( \ - (PCHAR)(address) - \ - (PCHAR)(&((type *)0)->field))) -#define PADDED_ADDR_SIZE sizeof(SOCKADDR_IN)+16 -typedef struct CompContext { - struct CompContext *next; - OVERLAPPED Overlapped; - apr_socket_t *sock; - SOCKET accept_socket; - char buff[2*PADDED_ADDR_SIZE]; - struct sockaddr *sa_server; - int sa_server_len; - struct sockaddr *sa_client; - int sa_client_len; - apr_pool_t *ptrans; - apr_bucket_alloc_t *ba; -} COMP_CONTEXT, *PCOMP_CONTEXT; - -typedef enum { - IOCP_CONNECTION_ACCEPTED = 1, - IOCP_WAIT_FOR_RECEIVE = 2, - IOCP_WAIT_FOR_TRANSMITFILE = 3, - IOCP_SHUTDOWN = 4 -} io_state_e; - -AP_DECLARE(PCOMP_CONTEXT) mpm_get_completion_context(void); -AP_DECLARE(void) mpm_recycle_completion_context(PCOMP_CONTEXT pCompContext); -AP_DECLARE(apr_status_t) mpm_post_completion_context(PCOMP_CONTEXT pCompContext, io_state_e state); -void hold_console_open_on_error(void); -#endif /* APACHE_MPM_WINNT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/nt_eventlog.c b/rubbos/app/httpd-2.0.64/server/mpm/winnt/nt_eventlog.c deleted file mode 100644 index 37a349e8..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/nt_eventlog.c +++ /dev/null @@ -1,175 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define CORE_PRIVATE - -#include "httpd.h" -#include "http_log.h" -#include "mpm_winnt.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_portable.h" -#include "ap_regkey.h" - -static char *display_name = NULL; -static HANDLE stderr_thread = NULL; -static HANDLE stderr_ready; - -static DWORD WINAPI service_stderr_thread(LPVOID hPipe) -{ - HANDLE hPipeRead = (HANDLE) hPipe; - HANDLE hEventSource; - char errbuf[256]; - char *errmsg = errbuf; - const char *errarg[9]; - DWORD errres; - ap_regkey_t *regkey; - apr_status_t rv; - apr_pool_t *p; - - apr_pool_sub_make(&p, NULL, NULL); - - errarg[0] = "The Apache service named"; - errarg[1] = display_name; - errarg[2] = "reported the following error:\r\n>>>"; - errarg[3] = errbuf; - errarg[4] = NULL; - errarg[5] = NULL; - errarg[6] = NULL; - errarg[7] = NULL; - errarg[8] = NULL; - - /* What are we going to do in here, bail on the user? not. */ - if ((rv = ap_regkey_open(®key, AP_REGKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\" - "EventLog\\Application\\Apache Service", - APR_READ | APR_WRITE | APR_CREATE, p)) - == APR_SUCCESS) - { - DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | - EVENTLOG_INFORMATION_TYPE; - - /* The stock message file */ - ap_regkey_value_set(regkey, "EventMessageFile", - "%SystemRoot%\\System32\\netmsg.dll", - AP_REGKEY_EXPAND, p); - - ap_regkey_value_raw_set(regkey, "TypesSupported", &dwData, - sizeof(dwData), REG_DWORD, p); - ap_regkey_close(regkey); - } - - hEventSource = RegisterEventSourceW(NULL, L"Apache Service"); - - SetEvent(stderr_ready); - - while (ReadFile(hPipeRead, errmsg, 1, &errres, NULL) && (errres == 1)) - { - if ((errmsg > errbuf) || !apr_isspace(*errmsg)) - { - ++errmsg; - if ((*(errmsg - 1) == '\n') - || (errmsg >= errbuf + sizeof(errbuf) - 1)) - { - while ((errmsg > errbuf) && apr_isspace(*(errmsg - 1))) { - --errmsg; - } - *errmsg = '\0'; - - /* Generic message: '%1 %2 %3 %4 %5 %6 %7 %8 %9' - * The event code in netmsg.dll is 3299 - */ - ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, - 3299, NULL, 9, 0, errarg, NULL); - errmsg = errbuf; - } - } - } - - if ((errres = GetLastError()) != ERROR_BROKEN_PIPE) { - apr_snprintf(errbuf, sizeof(errbuf), - "Win32 error %d reading stderr pipe stream\r\n", - GetLastError()); - - ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, - 3299, NULL, 9, 0, errarg, NULL); - } - - CloseHandle(hPipeRead); - DeregisterEventSource(hEventSource); - CloseHandle(stderr_thread); - stderr_thread = NULL; - apr_pool_destroy(p); - return 0; -} - - -void mpm_nt_eventlog_stderr_flush(void) -{ - HANDLE cleanup_thread = stderr_thread; - - if (cleanup_thread) { - HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE); - fclose(stderr); - CloseHandle(hErr); - WaitForSingleObject(cleanup_thread, 30000); - CloseHandle(cleanup_thread); - } -} - - -void mpm_nt_eventlog_stderr_open(char *argv0, apr_pool_t *p) -{ - SECURITY_ATTRIBUTES sa; - HANDLE hProc = GetCurrentProcess(); - HANDLE hPipeRead = NULL; - HANDLE hPipeWrite = NULL; - HANDLE hDup = NULL; - DWORD threadid; - apr_file_t *eventlog_file; - apr_file_t *stderr_file; - - display_name = argv0; - - /* Create a pipe to send stderr messages to the system error log. - * - * _dup2() duplicates the write handle inheritable for us. - */ - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = FALSE; - CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0); - ap_assert(hPipeRead && hPipeWrite); - - stderr_ready = CreateEvent(NULL, FALSE, FALSE, NULL); - stderr_thread = CreateThread(NULL, 0, service_stderr_thread, - (LPVOID) hPipeRead, 0, &threadid); - ap_assert(stderr_ready && stderr_thread); - - WaitForSingleObject(stderr_ready, INFINITE); - - if ((apr_file_open_stderr(&stderr_file, p) - == APR_SUCCESS) - && (apr_os_file_put(&eventlog_file, &hPipeWrite, APR_WRITE, p) - == APR_SUCCESS)) - apr_file_dup2(stderr_file, eventlog_file, p); - - /* The code above _will_ corrupt the StdHandle... - * and we must do so anyways. We set this up only - * after we initialized the posix stderr API. - */ - ap_open_stderr_log(p); -} diff --git a/rubbos/app/httpd-2.0.64/server/mpm/winnt/service.c b/rubbos/app/httpd-2.0.64/server/mpm/winnt/service.c deleted file mode 100644 index 8739dc08..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/winnt/service.c +++ /dev/null @@ -1,1346 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This module ALONE requires the window message API from user.h - * and the default APR include of windows.h will omit it, so - * preload the API symbols now... - */ - -#define CORE_PRIVATE -#define _WINUSER_ - -#include "httpd.h" -#include "http_log.h" -#include "mpm_winnt.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "ap_regkey.h" - -#ifdef NOUSER -#undef NOUSER -#endif -#undef _WINUSER_ -#include <winuser.h> - -static char *mpm_service_name = NULL; -static char *mpm_display_name = NULL; - -static struct -{ - HANDLE mpm_thread; /* primary thread handle of the apache server */ - HANDLE service_thread; /* thread service/monitor handle */ - DWORD service_thread_id;/* thread service/monitor ID */ - HANDLE service_init; /* controller thread init mutex */ - HANDLE service_term; /* NT service thread kill signal */ - SERVICE_STATUS ssStatus; - SERVICE_STATUS_HANDLE hServiceStatus; -} globdat; - -static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); - - -#define PRODREGKEY "SOFTWARE\\" AP_SERVER_BASEVENDOR "\\" \ - AP_SERVER_BASEPRODUCT "\\" AP_SERVER_BASEREVISION - -/* - * Get the server root from the registry into 'dir' which is - * size bytes long. Returns 0 if the server root was found - * or if the serverroot key does not exist (in which case - * dir will contain an empty string), or -1 if there was - * an error getting the key. - */ -apr_status_t ap_registry_get_server_root(apr_pool_t *p, char **buf) -{ - apr_status_t rv; - ap_regkey_t *key; - - if ((rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, PRODREGKEY, - APR_READ, p)) == APR_SUCCESS) { - rv = ap_regkey_value_get(buf, key, "ServerRoot", p); - ap_regkey_close(key); - if (rv == APR_SUCCESS) - return rv; - } - - if ((rv = ap_regkey_open(&key, AP_REGKEY_CURRENT_USER, PRODREGKEY, - APR_READ, p)) == APR_SUCCESS) { - rv = ap_regkey_value_get(buf, key, "ServerRoot", p); - ap_regkey_close(key); - if (rv == APR_SUCCESS) - return rv; - } - - *buf = NULL; - return rv; -} - - -/* The service configuration's is stored under the following trees: - * - * HKLM\System\CurrentControlSet\Services\[service name] - * - * \DisplayName - * \ImagePath - * \Parameters\ConfigArgs - * - * For Win9x, the launch service command is stored under: - * - * HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices\[service name] - */ - - -/* exit() for Win32 is macro mapped (horrible, we agree) that allows us - * to catch the non-zero conditions and inform the console process that - * the application died, and hang on to the console a bit longer. - * - * The macro only maps for http_main.c and other sources that include - * the service.h header, so we best assume it's an error to exit from - * _any_ other module. - * - * If real_exit_code is reset to 0, it will not be set or trigger this - * behavior on exit. All service and child processes are expected to - * reset this flag to zero to avoid undesireable side effects. - */ -AP_DECLARE_DATA int real_exit_code = 1; - -void hold_console_open_on_error(void) -{ - HANDLE hConIn; - HANDLE hConErr; - DWORD result; - time_t start; - time_t remains; - char *msg = "Note the errors or messages above, " - "and press the <ESC> key to exit. "; - CONSOLE_SCREEN_BUFFER_INFO coninfo; - INPUT_RECORD in; - char count[16]; - - if (!real_exit_code) - return; - hConIn = GetStdHandle(STD_INPUT_HANDLE); - hConErr = GetStdHandle(STD_ERROR_HANDLE); - if ((hConIn == INVALID_HANDLE_VALUE) || (hConErr == INVALID_HANDLE_VALUE)) - return; - if (!WriteConsole(hConErr, msg, strlen(msg), &result, NULL) || !result) - return; - if (!GetConsoleScreenBufferInfo(hConErr, &coninfo)) - return; - if (!SetConsoleMode(hConIn, ENABLE_MOUSE_INPUT | 0x80)) - return; - - start = time(NULL); - do - { - while (PeekConsoleInput(hConIn, &in, 1, &result) && result) - { - if (!ReadConsoleInput(hConIn, &in, 1, &result) || !result) - return; - if ((in.EventType == KEY_EVENT) && in.Event.KeyEvent.bKeyDown - && (in.Event.KeyEvent.uChar.AsciiChar == 27)) - return; - if (in.EventType == MOUSE_EVENT - && (in.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)) - return; - } - remains = ((start + 30) - time(NULL)); - sprintf (count, "%d...", remains); - if (!SetConsoleCursorPosition(hConErr, coninfo.dwCursorPosition)) - return; - if (!WriteConsole(hConErr, count, strlen(count), &result, NULL) - || !result) - return; - } - while ((remains > 0) && WaitForSingleObject(hConIn, 1000) != WAIT_FAILED); -} - -static BOOL die_on_logoff = FALSE; - -static LRESULT CALLBACK monitor_service_9x_proc(HWND hWnd, UINT msg, - WPARAM wParam, LPARAM lParam) -{ -/* This is the WndProc procedure for our invisible window. - * When the user shuts down the system, this window is sent - * a signal WM_ENDSESSION. We clean up by signaling Apache - * to shut down, and idle until Apache's primary thread quits. - */ - if ((msg == WM_ENDSESSION) - && (die_on_logoff || (lParam != ENDSESSION_LOGOFF))) - { - ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); - if (wParam) - /* Don't leave this message until we are dead! */ - WaitForSingleObject(globdat.mpm_thread, 30000); - return 0; - } - return (DefWindowProc(hWnd, msg, wParam, lParam)); -} - -static DWORD WINAPI monitor_service_9x_thread(void *service_name) -{ - /* When running as a service under Windows 9x, there is no console - * window present, and no ConsoleCtrlHandler to call when the system - * is shutdown. If the WatchWindow thread is created with a NULL - * service_name argument, then the ...SystemMonitor window class is - * used to create the "Apache" window to watch for logoff and shutdown. - * If the service_name is provided, the ...ServiceMonitor window class - * is used to create the window named by the service_name argument, - * and the logoff message is ignored. - */ - WNDCLASS wc; - HWND hwndMain; - MSG msg; - - wc.style = CS_GLOBALCLASS; - wc.lpfnWndProc = monitor_service_9x_proc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = NULL; - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - if (service_name) - wc.lpszClassName = "ApacheWin95ServiceMonitor"; - else - wc.lpszClassName = "ApacheWin95SystemMonitor"; - - die_on_logoff = service_name ? FALSE : TRUE; - - if (!RegisterClass(&wc)) - { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), - NULL, "Could not register window class for WatchWindow"); - globdat.service_thread_id = 0; - return 0; - } - - /* Create an invisible window */ - hwndMain = CreateWindow(wc.lpszClassName, - service_name ? (char *) service_name : "Apache", - WS_OVERLAPPEDWINDOW & ~WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, NULL, NULL, NULL, NULL); - - if (!hwndMain) - { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), - NULL, "Could not create WatchWindow"); - globdat.service_thread_id = 0; - return 0; - } - - /* If we succeed, eliminate the console window. - * Signal the parent we are all set up, and - * watch the message queue while the window lives. - */ - FreeConsole(); - SetEvent(globdat.service_init); - - while (GetMessage(&msg, NULL, 0, 0)) - { - if (msg.message == WM_CLOSE) - DestroyWindow(hwndMain); - else { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - globdat.service_thread_id = 0; - return 0; -} - - -static BOOL CALLBACK console_control_handler(DWORD ctrl_type) -{ - switch (ctrl_type) - { - case CTRL_BREAK_EVENT: - fprintf(stderr, "Apache server restarting...\n"); - ap_signal_parent(SIGNAL_PARENT_RESTART); - return TRUE; - case CTRL_C_EVENT: - fprintf(stderr, "Apache server interrupted...\n"); - /* for Interrupt signals, shut down the server. - * Tell the system we have dealt with the signal - * without waiting for Apache to terminate. - */ - ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); - return TRUE; - - case CTRL_CLOSE_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - /* for Terminate signals, shut down the server. - * Wait for Apache to terminate, but respond - * after a reasonable time to tell the system - * that we did attempt to shut ourself down. - * THESE EVENTS WILL NOT OCCUR UNDER WIN9x! - */ - fprintf(stderr, "Apache server shutdown initiated...\n"); - ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); - Sleep(30000); - return TRUE; - } - - /* We should never get here, but this is (mostly) harmless */ - return FALSE; -} - - -static void stop_console_handler(void) -{ - SetConsoleCtrlHandler(console_control_handler, FALSE); -} - - -void mpm_start_console_handler(void) -{ - SetConsoleCtrlHandler(console_control_handler, TRUE); - atexit(stop_console_handler); -} - - -/* Special situation - children of services need to mind their - * P's & Q's and wait quietly, ignoring the mean OS signaling - * shutdown and other horrors, to kill them gracefully... - */ - -static BOOL CALLBACK child_control_handler(DWORD ctrl_type) -{ - switch (ctrl_type) - { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - /* for Interrupt signals, ignore them. - * The system will also signal the parent process, - * which will terminate Apache. - */ - return TRUE; - - case CTRL_CLOSE_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - /* for Shutdown signals, ignore them, but... . - * The system will also signal the parent process, - * which will terminate Apache, so we need to wait. - */ - Sleep(30000); - return TRUE; - } - - /* We should never get here, but this is (mostly) harmless */ - return FALSE; -} - - -static void stop_child_console_handler(void) -{ - SetConsoleCtrlHandler(child_control_handler, FALSE); -} - - -void mpm_start_child_console_handler(void) -{ - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { - FreeConsole(); - } - else - { - SetConsoleCtrlHandler(child_control_handler, TRUE); - atexit(stop_child_console_handler); - } -} - - -/********************************** - WinNT service control management - **********************************/ - -static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint) -{ - static int checkPoint = 1; - int rv = APR_SUCCESS; - - if (globdat.hServiceStatus) - { - if (currentState == SERVICE_RUNNING) { - globdat.ssStatus.dwWaitHint = 0; - globdat.ssStatus.dwCheckPoint = 0; - globdat.ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - } - else if (currentState == SERVICE_STOPPED) { - globdat.ssStatus.dwWaitHint = 0; - globdat.ssStatus.dwCheckPoint = 0; - if (!exitCode && globdat.ssStatus.dwCurrentState - != SERVICE_STOP_PENDING) { - /* An unexpected exit? Better to error! */ - exitCode = 1; - } - if (exitCode) { - globdat.ssStatus.dwWin32ExitCode =ERROR_SERVICE_SPECIFIC_ERROR; - globdat.ssStatus.dwServiceSpecificExitCode = exitCode; - } - } - else { - globdat.ssStatus.dwCheckPoint = ++checkPoint; - globdat.ssStatus.dwControlsAccepted = 0; - if(waitHint) - globdat.ssStatus.dwWaitHint = waitHint; - } - - globdat.ssStatus.dwCurrentState = currentState; - - rv = SetServiceStatus(globdat.hServiceStatus, &globdat.ssStatus); - } - return(rv); -} - -/* Set the service description regardless of platform. - * We revert to set_service_description on NT/9x, the - * very long way so any Apache management program can grab the - * description. This would be bad on Win2000, since it wouldn't - * notify the service control manager of the name change. - */ - -/* borrowed from mpm_winnt.c */ -extern apr_pool_t *pconf; - -/* Windows 2000 alone supports ChangeServiceConfig2 in order to - * register our server_version string... so we need some fixups - * to avoid binding to that function if we are on WinNT/9x. - */ -static void set_service_description(void) -{ - const char *full_description; - SC_HANDLE schSCManager; - BOOL ret = 0; - - /* Nothing to do if we are a console - */ - if (!mpm_service_name) - return; - - /* Time to fix up the description, upon each successful restart - */ - full_description = ap_get_server_version(); - - if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - && (osver.dwMajorVersion > 4) - && (ChangeServiceConfig2) - && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) - { - SC_HANDLE schService = OpenService(schSCManager, mpm_service_name, - SERVICE_CHANGE_CONFIG); - if (schService) { - /* Cast is necessary, ChangeServiceConfig2 handles multiple - * object types, some volatile, some not. - */ - /* ###: utf-ize */ - if (ChangeServiceConfig2(schService, - 1 /* SERVICE_CONFIG_DESCRIPTION */, - (LPVOID) &full_description)) { - full_description = NULL; - } - CloseServiceHandle(schService); - } - CloseServiceHandle(schSCManager); - } - - if (full_description) - { - char szPath[MAX_PATH]; - ap_regkey_t *svckey; - apr_status_t rv; - - /* Find the Service key that Monitor Applications iterate */ - apr_snprintf(szPath, sizeof(szPath), - "SYSTEM\\CurrentControlSet\\Services\\%s", - mpm_service_name); - rv = ap_regkey_open(&svckey, AP_REGKEY_LOCAL_MACHINE, szPath, - APR_READ | APR_WRITE, pconf); - if (rv != APR_SUCCESS) { - return; - } - /* Attempt to set the Description value for our service */ - ap_regkey_value_set(svckey, "Description", full_description, 0, pconf); - ap_regkey_close(svckey); - } -} - -/* handle the SCM's ControlService() callbacks to our service */ - -static VOID WINAPI service_nt_ctrl(DWORD dwCtrlCode) -{ - if (dwCtrlCode == SERVICE_CONTROL_STOP) - { - ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); - ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 30000); - return; - } - if (dwCtrlCode == SERVICE_APACHE_RESTART) - { - ap_signal_parent(SIGNAL_PARENT_RESTART); - ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000); - return; - } - - ReportStatusToSCMgr(globdat.ssStatus.dwCurrentState, NO_ERROR, 0); -} - - -/* service_nt_main_fn is outside of the call stack and outside of the - * primary server thread... so now we _really_ need a placeholder! - * The winnt_rewrite_args has created and shared mpm_new_argv with us. - */ -extern apr_array_header_t *mpm_new_argv; - -/* ###: utf-ize */ -static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) -{ - const char *ignored; - - /* args and service names live in the same pool */ - mpm_service_set_name(mpm_new_argv->pool, &ignored, argv[0]); - - memset(&globdat.ssStatus, 0, sizeof(globdat.ssStatus)); - globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; - globdat.ssStatus.dwCheckPoint = 1; - - /* ###: utf-ize */ - if (!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], service_nt_ctrl))) - { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), - NULL, "Failure registering service handler"); - return; - } - - /* Report status, no errors, and buy 3 more seconds */ - ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000); - - /* We need to append all the command arguments passed via StartService() - * to our running service... which just got here via the SCM... - * but we hvae no interest in argv[0] for the mpm_new_argv list. - */ - if (argc > 1) - { - char **cmb_data; - - mpm_new_argv->nalloc = mpm_new_argv->nelts + argc - 1; - cmb_data = malloc(mpm_new_argv->nalloc * sizeof(const char *)); - - /* mpm_new_argv remains first (of lower significance) */ - memcpy (cmb_data, mpm_new_argv->elts, - mpm_new_argv->elt_size * mpm_new_argv->nelts); - - /* Service args follow from StartService() invocation */ - memcpy (cmb_data + mpm_new_argv->nelts, argv + 1, - mpm_new_argv->elt_size * (argc - 1)); - - /* The replacement arg list is complete */ - mpm_new_argv->elts = (char *)cmb_data; - mpm_new_argv->nelts = mpm_new_argv->nalloc; - } - - /* Let the main thread continue now... but hang on to the - * signal_monitor event so we can take further action - */ - SetEvent(globdat.service_init); - - WaitForSingleObject(globdat.service_term, INFINITE); -} - - -DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) -{ - apr_status_t rv = APR_SUCCESS; - - SERVICE_TABLE_ENTRY dispatchTable[] = - { - { "", service_nt_main_fn }, - { NULL, NULL } - }; - - /* ###: utf-ize */ - if (!StartServiceCtrlDispatcher(dispatchTable)) - { - /* This is a genuine failure of the SCM. */ - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "Error starting service control dispatcher"); - } - - return (rv); -} - - -apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, - const char *set_name) -{ - char key_name[MAX_PATH]; - ap_regkey_t *key; - apr_status_t rv; - - /* ### Needs improvement, on Win2K the user can _easily_ - * change the display name to a string that doesn't reflect - * the internal service name + whitespace! - */ - mpm_service_name = apr_palloc(p, strlen(set_name) + 1); - apr_collapse_spaces((char*) mpm_service_name, set_name); - apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); - rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf); - if (rv == APR_SUCCESS) { - rv = ap_regkey_value_get(&mpm_display_name, key, "DisplayName", pconf); - ap_regkey_close(key); - } - if (rv != APR_SUCCESS) { - /* Take the given literal name if there is no service entry */ - mpm_display_name = apr_pstrdup(p, set_name); - } - *display_name = mpm_display_name; - return rv; -} - - -apr_status_t mpm_merge_service_args(apr_pool_t *p, - apr_array_header_t *args, - int fixed_args) -{ - apr_array_header_t *svc_args = NULL; - char conf_key[MAX_PATH]; - char **cmb_data; - apr_status_t rv; - ap_regkey_t *key; - - apr_snprintf(conf_key, sizeof(conf_key), SERVICEPARAMS, mpm_service_name); - rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, conf_key, APR_READ, p); - if (rv == APR_SUCCESS) { - rv = ap_regkey_value_array_get(&svc_args, key, "ConfigArgs", p); - ap_regkey_close(key); - } - if (rv != APR_SUCCESS) { - if (rv == ERROR_FILE_NOT_FOUND) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, - "No ConfigArgs registered for %s, perhaps " - "this service is not installed?", - mpm_service_name); - return APR_SUCCESS; - } - else - return (rv); - } - - if (!svc_args || svc_args->nelts == 0) { - return (APR_SUCCESS); - } - - /* Now we have the mpm_service_name arg, and the mpm_runservice_nt() - * call appended the arguments passed by StartService(), so it's - * time to _prepend_ the default arguments for the server from - * the service's default arguments (all others override them)... - */ - args->nalloc = args->nelts + svc_args->nelts; - cmb_data = malloc(args->nalloc * sizeof(const char *)); - - /* First three args (argv[0], -f, path) remain first */ - memcpy(cmb_data, args->elts, args->elt_size * fixed_args); - - /* Service args follow from service registry array */ - memcpy(cmb_data + fixed_args, svc_args->elts, - svc_args->elt_size * svc_args->nelts); - - /* Remaining new args follow */ - memcpy(cmb_data + fixed_args + svc_args->nelts, - (const char **)args->elts + fixed_args, - args->elt_size * (args->nelts - fixed_args)); - - args->elts = (char *)cmb_data; - args->nelts = args->nalloc; - - return APR_SUCCESS; -} - - -void service_stopped(void) -{ - /* Still have a thread & window to clean up, so signal now */ - if (globdat.service_thread) - { - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - /* Stop logging to the event log */ - mpm_nt_eventlog_stderr_flush(); - - /* Cause the service_nt_main_fn to complete */ - ReleaseMutex(globdat.service_term); - - ReportStatusToSCMgr(SERVICE_STOPPED, // service state - NO_ERROR, // exit code - 0); // wait hint - } - else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ - { - RegisterServiceProcess(0, 0); - PostThreadMessage(globdat.service_thread_id, WM_CLOSE, 0, 0); - } - - WaitForSingleObject(globdat.service_thread, 5000); - CloseHandle(globdat.service_thread); - } -} - - -apr_status_t mpm_service_to_start(const char **display_name, apr_pool_t *p) -{ - HANDLE hProc = GetCurrentProcess(); - HANDLE hThread = GetCurrentThread(); - HANDLE waitfor[2]; - - /* Prevent holding open the (hidden) console */ - real_exit_code = 0; - - /* GetCurrentThread returns a psuedo-handle, we need - * a real handle for another thread to wait upon. - */ - if (!DuplicateHandle(hProc, hThread, hProc, &(globdat.mpm_thread), - 0, FALSE, DUPLICATE_SAME_ACCESS)) { - return APR_ENOTHREAD; - } - - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - globdat.service_init = CreateEvent(NULL, FALSE, FALSE, NULL); - globdat.service_term = CreateMutex(NULL, TRUE, NULL); - if (!globdat.service_init || !globdat.service_term) { - return APR_EGENERAL; - } - - globdat.service_thread = CreateThread(NULL, 0, service_nt_dispatch_thread, - NULL, 0, &globdat.service_thread_id); - } - else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ - { - if (!RegisterServiceProcess(0, 1)) - return GetLastError(); - - globdat.service_init = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!globdat.service_init) { - return APR_EGENERAL; - } - - globdat.service_thread = CreateThread(NULL, 0, monitor_service_9x_thread, - (LPVOID) mpm_service_name, 0, - &globdat.service_thread_id); - } - - if (!globdat.service_thread) { - return APR_ENOTHREAD; - } - - waitfor[0] = globdat.service_init; - waitfor[1] = globdat.service_thread; - - /* Wait for controlling thread init or termination */ - if (WaitForMultipleObjects(2, waitfor, FALSE, 10000) != WAIT_OBJECT_0) { - return APR_ENOTHREAD; - } - - atexit(service_stopped); - *display_name = mpm_display_name; - return APR_SUCCESS; -} - - -apr_status_t mpm_service_started(void) -{ - set_service_description(); - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - ReportStatusToSCMgr(SERVICE_RUNNING, // service state - NO_ERROR, // exit code - 0); // wait hint - } - return APR_SUCCESS; -} - - -void mpm_service_stopping(void) -{ - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - ReportStatusToSCMgr(SERVICE_STOP_PENDING, // service state - NO_ERROR, // exit code - 30000); // wait hint -} - - -apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, - const char * const * argv, int reconfig) -{ - char key_name[MAX_PATH]; - char exe_path[MAX_PATH]; - char *launch_cmd; - ap_regkey_t *key; - apr_status_t rv; - - fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" - : "Installing the %s service\n", mpm_display_name); - - /* ###: utf-ize */ - if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) - { - apr_status_t rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "GetModuleFileName failed"); - return rv; - } - - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - SC_HANDLE schService; - SC_HANDLE schSCManager; - - schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ - SC_MANAGER_CREATE_SERVICE); - if (!schSCManager) { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "Failed to open the WinNT service manager"); - return (rv); - } - - launch_cmd = apr_psprintf(ptemp, "\"%s\" -k runservice", exe_path); - - if (reconfig) { - /* ###: utf-ize */ - schService = OpenService(schSCManager, mpm_service_name, - SERVICE_CHANGE_CONFIG); - if (!schService) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, - apr_get_os_error(), NULL, - "OpenService failed"); - } - /* ###: utf-ize */ - else if (!ChangeServiceConfig(schService, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - launch_cmd, NULL, NULL, - "Tcpip\0Afd\0", NULL, NULL, - mpm_display_name)) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, - apr_get_os_error(), NULL, - "ChangeServiceConfig failed"); - /* !schService aborts configuration below */ - CloseServiceHandle(schService); - schService = NULL; - } - } - else { - /* RPCSS is the Remote Procedure Call (RPC) Locator required - * for DCOM communication pipes. I am far from convinced we - * should add this to the default service dependencies, but - * be warned that future apache modules or ISAPI dll's may - * depend on it. - */ - /* ###: utf-ize */ - schService = CreateService(schSCManager, // SCManager database - mpm_service_name, // name of service - mpm_display_name, // name to display - SERVICE_ALL_ACCESS, // access required - SERVICE_WIN32_OWN_PROCESS, // service type - SERVICE_AUTO_START, // start type - SERVICE_ERROR_NORMAL, // error control type - launch_cmd, // service's binary - NULL, // no load svc group - NULL, // no tag identifier - "Tcpip\0Afd\0", // dependencies - NULL, // use SYSTEM account - NULL); // no password - - if (!schService) - { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "Failed to create WinNT Service Profile"); - CloseServiceHandle(schSCManager); - return (rv); - } - } - - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - } - else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ - { - /* Store the launch command in the registry */ - launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", - exe_path, mpm_service_name); - rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, SERVICECONFIG9X, - APR_READ | APR_WRITE | APR_CREATE, pconf); - if (rv == APR_SUCCESS) { - rv = ap_regkey_value_set(key, mpm_service_name, - launch_cmd, 0, pconf); - ap_regkey_close(key); - } - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to add the RunServices registry entry.", - mpm_display_name); - return (rv); - } - - apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); - rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, - APR_READ | APR_WRITE | APR_CREATE, pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to create the registry service key.", - mpm_display_name); - return (rv); - } - rv = ap_regkey_value_set(key, "ImagePath", launch_cmd, 0, pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to store ImagePath in the registry.", - mpm_display_name); - ap_regkey_close(key); - return (rv); - } - rv = ap_regkey_value_set(key, "DisplayName", - mpm_display_name, 0, pconf); - ap_regkey_close(key); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to store DisplayName in the registry.", - mpm_display_name); - return (rv); - } - } - - set_service_description(); - - /* For both WinNT & Win9x store the service ConfigArgs in the registry... - */ - apr_snprintf(key_name, sizeof(key_name), SERVICEPARAMS, mpm_service_name); - rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, - APR_READ | APR_WRITE | APR_CREATE, pconf); - if (rv == APR_SUCCESS) { - rv = ap_regkey_value_array_set(key, "ConfigArgs", argc, argv, pconf); - ap_regkey_close(key); - } - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to store the ConfigArgs in the registry.", - mpm_display_name); - return (rv); - } - fprintf(stderr,"The %s service is successfully installed.\n", mpm_display_name); - return APR_SUCCESS; -} - - -apr_status_t mpm_service_uninstall(void) -{ - char key_name[MAX_PATH]; - apr_status_t rv; - - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - SC_HANDLE schService; - SC_HANDLE schSCManager; - - fprintf(stderr,"Removing the %s service\n", mpm_display_name); - - schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ - SC_MANAGER_CONNECT); - if (!schSCManager) { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "Failed to open the WinNT service manager."); - return (rv); - } - - /* ###: utf-ize */ - schService = OpenService(schSCManager, mpm_service_name, DELETE); - - if (!schService) { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: OpenService failed", mpm_display_name); - return (rv); - } - - /* assure the service is stopped before continuing - * - * This may be out of order... we might not be able to be - * granted all access if the service is running anyway. - * - * And do we want to make it *this easy* for them - * to uninstall their service unintentionally? - */ - // ap_stop_service(schService); - - if (DeleteService(schService) == 0) { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to delete the service.", mpm_display_name); - return (rv); - } - - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - } - else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ - { - apr_status_t rv2, rv3; - ap_regkey_t *key; - fprintf(stderr,"Removing the %s service\n", mpm_display_name); - - /* TODO: assure the service is stopped before continuing */ - - rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, SERVICECONFIG9X, - APR_READ | APR_WRITE | APR_CREATE, pconf); - if (rv == APR_SUCCESS) { - rv = ap_regkey_value_remove(key, mpm_service_name, pconf); - ap_regkey_close(key); - } - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to remove the RunServices registry " - "entry.", mpm_display_name); - } - - /* we blast Services/us, not just the Services/us/Parameters branch */ - apr_snprintf(key_name, sizeof(key_name), SERVICEPARAMS, mpm_service_name); - rv2 = ap_regkey_remove(AP_REGKEY_LOCAL_MACHINE, key_name, pconf); - apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); - rv3 = ap_regkey_remove(AP_REGKEY_LOCAL_MACHINE, key_name, pconf); - rv2 = (rv2 != APR_SUCCESS) ? rv2 : rv3; - if (rv2 != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv2, NULL, - "%s: Failed to remove the service config from the " - "registry.", mpm_display_name); - } - rv = (rv != APR_SUCCESS) ? rv : rv2; - if (rv != APR_SUCCESS) - return rv; - } - fprintf(stderr,"The %s service has been removed successfully.\n", mpm_display_name); - return APR_SUCCESS; -} - - -/* signal_service_transition is a simple thunk to signal the service - * and monitor its successful transition. If the signal passed is 0, - * then the caller is assumed to already have performed some service - * operation to be monitored (such as StartService), and no actual - * ControlService signal is sent. - */ - -static int signal_service_transition(SC_HANDLE schService, DWORD signal, DWORD pending, DWORD complete) -{ - if (signal && !ControlService(schService, signal, &globdat.ssStatus)) - return FALSE; - - do { - Sleep(1000); - if (!QueryServiceStatus(schService, &globdat.ssStatus)) - return FALSE; - } while (globdat.ssStatus.dwCurrentState == pending); - - return (globdat.ssStatus.dwCurrentState == complete); -} - - -apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, - const char * const * argv) -{ - apr_status_t rv; - - fprintf(stderr,"Starting the %s service\n", mpm_display_name); - - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - char **start_argv; - SC_HANDLE schService; - SC_HANDLE schSCManager; - - schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ - SC_MANAGER_CONNECT); - if (!schSCManager) { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "Failed to open the WinNT service manager"); - return (rv); - } - - /* ###: utf-ize */ - schService = OpenService(schSCManager, mpm_service_name, - SERVICE_START | SERVICE_QUERY_STATUS); - if (!schService) { - rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "%s: Failed to open the service.", mpm_display_name); - CloseServiceHandle(schSCManager); - return (rv); - } - - if (QueryServiceStatus(schService, &globdat.ssStatus) - && (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING)) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL, - "Service %s is already started!", mpm_display_name); - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - return 0; - } - - start_argv = malloc((argc + 1) * sizeof(const char **)); - memcpy(start_argv, argv, argc * sizeof(const char **)); - start_argv[argc] = NULL; - - rv = APR_EINIT; - /* ###: utf-ize */ - if (StartService(schService, argc, start_argv) - && signal_service_transition(schService, 0, /* test only */ - SERVICE_START_PENDING, - SERVICE_RUNNING)) - rv = APR_SUCCESS; - - if (rv != APR_SUCCESS) - rv = apr_get_os_error(); - - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - } - else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ - { - STARTUPINFO si; /* Filled in prior to call to CreateProcess */ - PROCESS_INFORMATION pi; /* filled in on call to CreateProcess */ - char exe_path[MAX_PATH]; - char exe_cmd[MAX_PATH * 4]; - char *next_arg; - int i; - - /* Locate the active top level window named service_name - * provided the class is ApacheWin95ServiceMonitor - */ - if (FindWindow("ApacheWin95ServiceMonitor", mpm_service_name)) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL, - "Service %s is already started!", mpm_display_name); - return 0; - } - - /* This may not appear intuitive, but Win9x will not allow a process - * to detach from the console without releasing the entire console. - * Ergo, we must spawn a new process for the service to get back our - * console window. - * The config is pre-flighted, so there should be no danger of failure. - */ - - if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) - { - apr_status_t rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, - "GetModuleFileName failed"); - return rv; - } - - apr_snprintf(exe_cmd, sizeof(exe_cmd), - "\"%s\" -n %s -k runservice", - exe_path, mpm_service_name); - next_arg = strchr(exe_cmd, '\0'); - for (i = 0; i < argc; ++i) { - apr_snprintf(next_arg, sizeof(exe_cmd) - (next_arg - exe_cmd), - " \"%s\"", argv[i]); - next_arg = strchr(exe_cmd, '\0'); - } - - memset(&si, 0, sizeof(si)); - memset(&pi, 0, sizeof(pi)); - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; /* This might be redundant */ - - rv = APR_EINIT; - if (CreateProcess(NULL, exe_cmd, NULL, NULL, FALSE, - DETACHED_PROCESS, /* Creation flags */ - NULL, NULL, &si, &pi)) - { - DWORD code; - while (GetExitCodeProcess(pi.hProcess, &code) == STILL_ACTIVE) { - if (FindWindow("ApacheWin95ServiceMonitor", mpm_service_name)) { - rv = APR_SUCCESS; - break; - } - Sleep (1000); - } - } - - if (rv != APR_SUCCESS) - rv = apr_get_os_error(); - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } - - if (rv == APR_SUCCESS) - fprintf(stderr,"The %s service is running.\n", mpm_display_name); - else - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "%s: Failed to start the service process.", - mpm_display_name); - - return rv; -} - - -/* signal is zero to stop, non-zero for restart */ - -void mpm_signal_service(apr_pool_t *ptemp, int signal) -{ - int success = FALSE; - - if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - SC_HANDLE schService; - SC_HANDLE schSCManager; - - schSCManager = OpenSCManager(NULL, NULL, // default machine & database - SC_MANAGER_CONNECT); - - if (!schSCManager) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, - "Failed to open the NT Service Manager"); - return; - } - - /* ###: utf-ize */ - schService = OpenService(schSCManager, mpm_service_name, - SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | - SERVICE_USER_DEFINED_CONTROL | - SERVICE_START | SERVICE_STOP); - - if (schService == NULL) { - /* Could not open the service */ - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, - "Failed to open the %s Service", mpm_display_name); - CloseServiceHandle(schSCManager); - return; - } - - if (!QueryServiceStatus(schService, &globdat.ssStatus)) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, - "Query of Service %s failed", mpm_display_name); - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - return; - } - - if (!signal && (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED)) { - fprintf(stderr,"The %s service is not started.\n", mpm_display_name); - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - return; - } - - fprintf(stderr,"The %s service is %s.\n", mpm_display_name, - signal ? "restarting" : "stopping"); - - if (!signal) - success = signal_service_transition(schService, - SERVICE_CONTROL_STOP, - SERVICE_STOP_PENDING, - SERVICE_STOPPED); - else if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) { - mpm_service_start(ptemp, 0, NULL); - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - return; - } - else - success = signal_service_transition(schService, - SERVICE_APACHE_RESTART, - SERVICE_START_PENDING, - SERVICE_RUNNING); - - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - } - else /* !isWindowsNT() */ - { - DWORD service_pid; - HANDLE hwnd; - char prefix[20]; - /* Locate the active top level window named service_name - * provided the class is ApacheWin95ServiceMonitor - */ - hwnd = FindWindow("ApacheWin95ServiceMonitor", mpm_service_name); - if (hwnd && GetWindowThreadProcessId(hwnd, &service_pid)) - globdat.ssStatus.dwCurrentState = SERVICE_RUNNING; - else - { - globdat.ssStatus.dwCurrentState = SERVICE_STOPPED; - if (!signal) { - fprintf(stderr,"The %s service is not started.\n", mpm_display_name); - return; - } - } - - fprintf(stderr,"The %s service is %s.\n", mpm_display_name, - signal ? "restarting" : "stopping"); - - apr_snprintf(prefix, sizeof(prefix), "ap%ld", (long)service_pid); - setup_signal_names(prefix); - - if (!signal) - { - int ticks = 60; - ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); - while (--ticks) - { - if (!IsWindow(hwnd)) { - success = TRUE; - break; - } - Sleep(1000); - } - } - else /* !stop */ - { - /* TODO: Aught to add a little test to the restart logic, and - * store the restart counter in the window's user dword. - * Then we can hang on and report a successful restart. But - * that's a project for another day. - */ - if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) { - mpm_service_start(ptemp, 0, NULL); - return; - } - else { - success = TRUE; - ap_signal_parent(SIGNAL_PARENT_RESTART); - } - } - } - - if (success) - fprintf(stderr,"The %s service has %s.\n", mpm_display_name, - signal ? "restarted" : "stopped"); - else - fprintf(stderr,"Failed to %s the %s service.\n", - signal ? "restart" : "stop", mpm_display_name); -} diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/.deps b/rubbos/app/httpd-2.0.64/server/mpm/worker/.deps deleted file mode 100644 index e69de29b..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/.deps +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/fdqueue.o b/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/fdqueue.o Binary files differdeleted file mode 100644 index fb4a5ad1..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/fdqueue.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/libworker.a b/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/libworker.a Binary files differdeleted file mode 100644 index b315573e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/libworker.a +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/libworker.la b/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/libworker.la deleted file mode 100644 index 464032f9..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/libworker.la +++ /dev/null @@ -1,35 +0,0 @@ -# libworker.la - a libtool library file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='' - -# Names of this library. -library_names='' - -# The name of the static archive. -old_library='libworker.a' - -# Libraries that this one depends upon. -dependency_libs=' -L/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/xml/expat/lib' - -# Version information for libworker. -current= -age= -revision= - -# Is this an already installed library? -installed=no - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='' diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/pod.o b/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/pod.o Binary files differdeleted file mode 100644 index 42e89371..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/pod.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/worker.o b/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/worker.o Binary files differdeleted file mode 100644 index dc560c2b..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/.libs/worker.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/Makefile b/rubbos/app/httpd-2.0.64/server/mpm/worker/Makefile deleted file mode 100644 index 6c812571..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -top_srcdir = /bottlenecks/rubbos/app/httpd-2.0.64 -top_builddir = /bottlenecks/rubbos/app/httpd-2.0.64 -srcdir = /bottlenecks/rubbos/app/httpd-2.0.64/server/mpm/worker -builddir = /bottlenecks/rubbos/app/httpd-2.0.64/server/mpm/worker -VPATH = /bottlenecks/rubbos/app/httpd-2.0.64/server/mpm/worker - -LTLIBRARY_NAME = libworker.la -LTLIBRARY_SOURCES = worker.c fdqueue.c pod.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/Makefile.in b/rubbos/app/httpd-2.0.64/server/mpm/worker/Makefile.in deleted file mode 100644 index b45b8483..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ - -LTLIBRARY_NAME = libworker.la -LTLIBRARY_SOURCES = worker.c fdqueue.c pod.c - -include $(top_srcdir)/build/ltlib.mk diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/config5.m4 b/rubbos/app/httpd-2.0.64/server/mpm/worker/config5.m4 deleted file mode 100644 index cc131348..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/config5.m4 +++ /dev/null @@ -1,6 +0,0 @@ -dnl ## XXX - Need a more thorough check of the proper flags to use - -if test "$MPM_NAME" = "worker" ; then - AC_CHECK_FUNCS(pthread_kill) - APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) -fi diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.c b/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.c deleted file mode 100644 index 17a819bf..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "fdqueue.h" - -struct fd_queue_info_t { - int idlers; - apr_thread_mutex_t *idlers_mutex; - apr_thread_cond_t *wait_for_idler; - int terminated; - int max_idlers; - apr_pool_t **recycled_pools; - int num_recycled; -}; - -static apr_status_t queue_info_cleanup(void *data_) -{ - fd_queue_info_t *qi = data_; - int i; - apr_thread_cond_destroy(qi->wait_for_idler); - apr_thread_mutex_destroy(qi->idlers_mutex); - for (i = 0; i < qi->num_recycled; i++) { - apr_pool_destroy(qi->recycled_pools[i]); - } - return APR_SUCCESS; -} - -apr_status_t ap_queue_info_create(fd_queue_info_t **queue_info, - apr_pool_t *pool, int max_idlers) -{ - apr_status_t rv; - fd_queue_info_t *qi; - - qi = apr_palloc(pool, sizeof(*qi)); - memset(qi, 0, sizeof(*qi)); - - rv = apr_thread_mutex_create(&qi->idlers_mutex, APR_THREAD_MUTEX_DEFAULT, - pool); - if (rv != APR_SUCCESS) { - return rv; - } - rv = apr_thread_cond_create(&qi->wait_for_idler, pool); - if (rv != APR_SUCCESS) { - return rv; - } - qi->recycled_pools = (apr_pool_t **)apr_palloc(pool, max_idlers * - sizeof(apr_pool_t *)); - qi->num_recycled = 0; - qi->max_idlers = max_idlers; - apr_pool_cleanup_register(pool, qi, queue_info_cleanup, - apr_pool_cleanup_null); - - *queue_info = qi; - - return APR_SUCCESS; -} - -apr_status_t ap_queue_info_set_idle(fd_queue_info_t *queue_info, - apr_pool_t *pool_to_recycle) -{ - apr_status_t rv; - rv = apr_thread_mutex_lock(queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - AP_DEBUG_ASSERT(queue_info->idlers >= 0); - AP_DEBUG_ASSERT(queue_info->num_recycled < queue_info->max_idlers); - if (pool_to_recycle) { - queue_info->recycled_pools[queue_info->num_recycled++] = - pool_to_recycle; - } - if (queue_info->idlers++ == 0) { - /* Only signal if we had no idlers before. */ - apr_thread_cond_signal(queue_info->wait_for_idler); - } - rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -} - -apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info, - apr_pool_t **recycled_pool) -{ - apr_status_t rv; - *recycled_pool = NULL; - rv = apr_thread_mutex_lock(queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - AP_DEBUG_ASSERT(queue_info->idlers >= 0); - while ((queue_info->idlers == 0) && (!queue_info->terminated)) { - rv = apr_thread_cond_wait(queue_info->wait_for_idler, - queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - apr_status_t rv2; - rv2 = apr_thread_mutex_unlock(queue_info->idlers_mutex); - if (rv2 != APR_SUCCESS) { - return rv2; - } - return rv; - } - } - queue_info->idlers--; /* Oh, and idler? Let's take 'em! */ - if (queue_info->num_recycled) { - *recycled_pool = - queue_info->recycled_pools[--queue_info->num_recycled]; - } - rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - else if (queue_info->terminated) { - return APR_EOF; - } - else { - return APR_SUCCESS; - } -} - -apr_status_t ap_queue_info_term(fd_queue_info_t *queue_info) -{ - apr_status_t rv; - rv = apr_thread_mutex_lock(queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - queue_info->terminated = 1; - apr_thread_cond_broadcast(queue_info->wait_for_idler); - rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -} - -/** - * Detects when the fd_queue_t is full. This utility function is expected - * to be called from within critical sections, and is not threadsafe. - */ -#define ap_queue_full(queue) ((queue)->nelts == (queue)->bounds) - -/** - * Detects when the fd_queue_t is empty. This utility function is expected - * to be called from within critical sections, and is not threadsafe. - */ -#define ap_queue_empty(queue) ((queue)->nelts == 0) - -/** - * Callback routine that is called to destroy this - * fd_queue_t when its pool is destroyed. - */ -static apr_status_t ap_queue_destroy(void *data) -{ - fd_queue_t *queue = data; - - /* Ignore errors here, we can't do anything about them anyway. - * XXX: We should at least try to signal an error here, it is - * indicative of a programmer error. -aaron */ - apr_thread_cond_destroy(queue->not_empty); - apr_thread_mutex_destroy(queue->one_big_mutex); - - return APR_SUCCESS; -} - -/** - * Initialize the fd_queue_t. - */ -apr_status_t ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a) -{ - int i; - apr_status_t rv; - - if ((rv = apr_thread_mutex_create(&queue->one_big_mutex, - APR_THREAD_MUTEX_DEFAULT, a)) != APR_SUCCESS) { - return rv; - } - if ((rv = apr_thread_cond_create(&queue->not_empty, a)) != APR_SUCCESS) { - return rv; - } - - queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t)); - queue->bounds = queue_capacity; - queue->nelts = 0; - - /* Set all the sockets in the queue to NULL */ - for (i = 0; i < queue_capacity; ++i) - queue->data[i].sd = NULL; - - apr_pool_cleanup_register(a, queue, ap_queue_destroy, apr_pool_cleanup_null); - - return APR_SUCCESS; -} - -/** - * Push a new socket onto the queue. Blocks if the queue is full. Once - * the push operation has completed, it signals other threads waiting - * in ap_queue_pop() that they may continue consuming sockets. - */ -apr_status_t ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p) -{ - fd_queue_elem_t *elem; - apr_status_t rv; - - if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - - AP_DEBUG_ASSERT(!queue->terminated); - AP_DEBUG_ASSERT(!ap_queue_full(queue)); - - elem = &queue->data[queue->nelts]; - elem->sd = sd; - elem->p = p; - queue->nelts++; - - apr_thread_cond_signal(queue->not_empty); - - if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - - return APR_SUCCESS; -} - -/** - * Retrieves the next available socket from the queue. If there are no - * sockets available, it will block until one becomes available. - * Once retrieved, the socket is placed into the address specified by - * 'sd'. - */ -apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p) -{ - fd_queue_elem_t *elem; - apr_status_t rv; - - if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - - /* Keep waiting until we wake up and find that the queue is not empty. */ - if (ap_queue_empty(queue)) { - if (!queue->terminated) { - apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex); - } - /* If we wake up and it's still empty, then we were interrupted */ - if (ap_queue_empty(queue)) { - rv = apr_thread_mutex_unlock(queue->one_big_mutex); - if (rv != APR_SUCCESS) { - return rv; - } - if (queue->terminated) { - return APR_EOF; /* no more elements ever again */ - } - else { - return APR_EINTR; - } - } - } - - elem = &queue->data[--queue->nelts]; - *sd = elem->sd; - *p = elem->p; -#ifdef AP_DEBUG - elem->sd = NULL; - elem->p = NULL; -#endif /* AP_DEBUG */ - - rv = apr_thread_mutex_unlock(queue->one_big_mutex); - return rv; -} - -apr_status_t ap_queue_interrupt_all(fd_queue_t *queue) -{ - apr_status_t rv; - - if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - apr_thread_cond_broadcast(queue->not_empty); - if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -} - -apr_status_t ap_queue_term(fd_queue_t *queue) -{ - apr_status_t rv; - - if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - /* we must hold one_big_mutex when setting this... otherwise, - * we could end up setting it and waking everybody up just after a - * would-be popper checks it but right before they block - */ - queue->terminated = 1; - if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { - return rv; - } - return ap_queue_interrupt_all(queue); -} diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.h b/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.h deleted file mode 100644 index 6dd55e03..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FDQUEUE_H -#define FDQUEUE_H -#include "httpd.h" -#include <stdlib.h> -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <apr_thread_mutex.h> -#include <apr_thread_cond.h> -#include <sys/types.h> -#if APR_HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <apr_errno.h> - -typedef struct fd_queue_info_t fd_queue_info_t; - -apr_status_t ap_queue_info_create(fd_queue_info_t **queue_info, - apr_pool_t *pool, int max_idlers); -apr_status_t ap_queue_info_set_idle(fd_queue_info_t *queue_info, - apr_pool_t *pool_to_recycle); -apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info, - apr_pool_t **recycled_pool); -apr_status_t ap_queue_info_term(fd_queue_info_t *queue_info); - -struct fd_queue_elem_t { - apr_socket_t *sd; - apr_pool_t *p; -}; -typedef struct fd_queue_elem_t fd_queue_elem_t; - -struct fd_queue_t { - fd_queue_elem_t *data; - int nelts; - int bounds; - apr_thread_mutex_t *one_big_mutex; - apr_thread_cond_t *not_empty; - int terminated; -}; -typedef struct fd_queue_t fd_queue_t; - -apr_status_t ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a); -apr_status_t ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p); -apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p); -apr_status_t ap_queue_interrupt_all(fd_queue_t *queue); -apr_status_t ap_queue_term(fd_queue_t *queue); - -#endif /* FDQUEUE_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.lo b/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.lo deleted file mode 100644 index 88d30c88..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.lo +++ /dev/null @@ -1,12 +0,0 @@ -# fdqueue.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/fdqueue.o' - -# Name of the non-PIC object. -non_pic_object='fdqueue.o' - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.o b/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.o Binary files differdeleted file mode 100644 index fb4a5ad1..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/fdqueue.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/libworker.la b/rubbos/app/httpd-2.0.64/server/mpm/worker/libworker.la deleted file mode 100644 index 464032f9..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/libworker.la +++ /dev/null @@ -1,35 +0,0 @@ -# libworker.la - a libtool library file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='' - -# Names of this library. -library_names='' - -# The name of the static archive. -old_library='libworker.a' - -# Libraries that this one depends upon. -dependency_libs=' -L/bottlenecks/rubbos/app/httpd-2.0.64/srclib/apr-util/xml/expat/lib' - -# Version information for libworker. -current= -age= -revision= - -# Is this an already installed library? -installed=no - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='' diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/mpm.h b/rubbos/app/httpd-2.0.64/server/mpm/worker/mpm.h deleted file mode 100644 index 31830c6c..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/mpm.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "scoreboard.h" -#include "unixd.h" - -#ifndef APACHE_MPM_WORKER_H -#define APACHE_MPM_WORKER_H - -#define WORKER_MPM - -#define MPM_NAME "Worker" - -#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -#define AP_MPM_WANT_WAIT_OR_TIMEOUT -#define AP_MPM_WANT_PROCESS_CHILD_STATUS -#define AP_MPM_WANT_SET_PIDFILE -#define AP_MPM_WANT_SET_SCOREBOARD -#define AP_MPM_WANT_SET_LOCKFILE -#define AP_MPM_WANT_SET_MAX_REQUESTS -#define AP_MPM_WANT_SET_COREDUMPDIR -#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -#define AP_MPM_WANT_SIGNAL_SERVER -#define AP_MPM_WANT_SET_MAX_MEM_FREE -#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER -#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK - -#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) -#define MPM_ACCEPT_FUNC unixd_accept - -extern int ap_threads_per_child; -extern int ap_max_daemons_limit; -extern server_rec *ap_server_conf; -extern char ap_coredump_dir[MAX_STRING_LEN]; - -#endif /* APACHE_MPM_WORKER_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/mpm_default.h b/rubbos/app/httpd-2.0.64/server/mpm/worker/mpm_default.h deleted file mode 100644 index d5a33989..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/mpm_default.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APACHE_MPM_DEFAULT_H -#define APACHE_MPM_DEFAULT_H - -/* Number of servers to spawn off by default --- also, if fewer than - * this free when the caretaker checks, it will spawn more. - */ -#ifndef DEFAULT_START_DAEMON -#define DEFAULT_START_DAEMON 3 -#endif - -/* Maximum number of *free* server processes --- more than this, and - * they will die off. - */ - -#ifndef DEFAULT_MAX_FREE_DAEMON -#define DEFAULT_MAX_FREE_DAEMON 10 -#endif - -/* Minimum --- fewer than this, and more will be created */ - -#ifndef DEFAULT_MIN_FREE_DAEMON -#define DEFAULT_MIN_FREE_DAEMON 3 -#endif - -#ifndef DEFAULT_THREADS_PER_CHILD -#define DEFAULT_THREADS_PER_CHILD 25 -#endif - -/* File used for accept locking, when we use a file */ -#ifndef DEFAULT_LOCKFILE -#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" -#endif - -/* Where the main/parent process's pid is logged */ -#ifndef DEFAULT_PIDLOG -#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" -#endif - -/* - * Interval, in microseconds, between scoreboard maintenance. - */ -#ifndef SCOREBOARD_MAINTENANCE_INTERVAL -#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 -#endif - -/* Number of requests to try to handle in a single process. If <= 0, - * the children don't die off. - */ -#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD -#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 -#endif - -#endif /* AP_MPM_DEFAULT_H */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.c b/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.c deleted file mode 100644 index 3a9a266e..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "pod.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - -AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod) -{ - apr_status_t rv; - - *pod = apr_palloc(p, sizeof(**pod)); - rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); - if (rv != APR_SUCCESS) { - return rv; - } -/* - apr_file_pipe_timeout_set((*pod)->pod_in, 0); -*/ - (*pod)->p = p; - - /* close these before exec. */ - apr_file_unset_inherit((*pod)->pod_in); - apr_file_unset_inherit((*pod)->pod_out); - - return APR_SUCCESS; -} - -AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod) -{ - char c; - apr_os_file_t fd; - int rc; - - /* we need to surface EINTR so we'll have to grab the - * native file descriptor and do the OS read() ourselves - */ - apr_os_file_get(&fd, pod->pod_in); - rc = read(fd, &c, 1); - if (rc == 1) { - switch(c) { - case RESTART_CHAR: - return AP_RESTART; - case GRACEFUL_CHAR: - return AP_GRACEFUL; - } - } - return AP_NORESTART; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod) -{ - apr_status_t rv; - - rv = apr_file_close(pod->pod_out); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_file_close(pod->pod_in); - if (rv != APR_SUCCESS) { - return rv; - } - return rv; -} - -static apr_status_t pod_signal_internal(ap_pod_t *pod, int graceful) -{ - apr_status_t rv; - char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; - apr_size_t one = 1; - - do { - rv = apr_file_write(pod->pod_out, &char_of_death, &one); - } while (APR_STATUS_IS_EINTR(rv)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, - "write pipe_of_death"); - } - return rv; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful) -{ - return pod_signal_internal(pod, graceful); -} - -AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful) -{ - int i; - apr_status_t rv = APR_SUCCESS; - - for (i = 0; i < num && rv == APR_SUCCESS; i++) { - rv = pod_signal_internal(pod, graceful); - } -} - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.h b/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.h deleted file mode 100644 index 21651e6f..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_strings.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "http_main.h" -#include "mpm.h" -#include "mpm_common.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "mpm_default.h" - -#define RESTART_CHAR '$' -#define GRACEFUL_CHAR '!' - -#define AP_RESTART 0 -#define AP_GRACEFUL 1 - -typedef struct ap_pod_t ap_pod_t; - -struct ap_pod_t { - apr_file_t *pod_in; - apr_file_t *pod_out; - apr_pool_t *p; -}; - -AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod); -AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod); -AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod); -AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful); -AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful); diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.lo b/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.lo deleted file mode 100644 index b284c939..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.lo +++ /dev/null @@ -1,12 +0,0 @@ -# pod.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/pod.o' - -# Name of the non-PIC object. -non_pic_object='pod.o' - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.o b/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.o Binary files differdeleted file mode 100644 index 42e89371..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/pod.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.c b/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.c deleted file mode 100644 index 6e0da647..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.c +++ /dev/null @@ -1,2136 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The purpose of this MPM is to fix the design flaws in the threaded - * model. Because of the way that pthreads and mutex locks interact, - * it is basically impossible to cleanly gracefully shutdown a child - * process if multiple threads are all blocked in accept. This model - * fixes those problems. - */ - -#include "apr.h" -#include "apr_portable.h" -#include "apr_strings.h" -#include "apr_file_io.h" -#include "apr_thread_proc.h" -#include "apr_signal.h" -#include "apr_thread_mutex.h" -#include "apr_proc_mutex.h" -#include "apr_poll.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#if APR_HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif -#ifdef HAVE_SYS_PROCESSOR_H -#include <sys/processor.h> /* for bindprocessor() */ -#endif - -#if !APR_HAS_THREADS -#error The Worker MPM requires APR threads, but they are unavailable. -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_config.h" /* for read_config */ -#include "http_core.h" /* for get_remote_host */ -#include "http_connection.h" -#include "ap_mpm.h" -#include "pod.h" -#include "mpm_common.h" -#include "ap_listen.h" -#include "scoreboard.h" -#include "fdqueue.h" -#include "mpm_default.h" - -#include <signal.h> -#include <limits.h> /* for INT_MAX */ - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_SERVER_LIMIT -#define DEFAULT_SERVER_LIMIT 16 -#endif - -/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_SERVER_LIMIT -#define MAX_SERVER_LIMIT 20000 -#endif - -/* Limit on the threads per process. Clients will be locked out if more than - * this * server_limit are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef DEFAULT_THREAD_LIMIT -#define DEFAULT_THREAD_LIMIT 64 -#endif - -/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want - * some sort of compile-time limit to help catch typos. - */ -#ifndef MAX_THREAD_LIMIT -#define MAX_THREAD_LIMIT 20000 -#endif - -/* - * Actual definitions of config globals - */ - -int ap_threads_per_child = 0; /* Worker threads per child */ -static int ap_daemons_to_start = 0; -static int min_spare_threads = 0; -static int max_spare_threads = 0; -static int ap_daemons_limit = 0; -static int server_limit = DEFAULT_SERVER_LIMIT; -static int first_server_limit; -static int thread_limit = DEFAULT_THREAD_LIMIT; -static int first_thread_limit; -static int changed_limit_at_restart; -static int dying = 0; -static int workers_may_exit = 0; -static int start_thread_may_exit = 0; -static int listener_may_exit = 0; -static int requests_this_child; -static int num_listensocks = 0; -static int resource_shortage = 0; -static fd_queue_t *worker_queue; -static fd_queue_info_t *worker_queue_info; -static int mpm_state = AP_MPMQ_STARTING; -static int sick_child_detected; - -/* The structure used to pass unique initialization info to each thread */ -typedef struct { - int pid; - int tid; - int sd; -} proc_info; - -/* Structure used to pass information to the thread responsible for - * creating the rest of the threads. - */ -typedef struct { - apr_thread_t **threads; - apr_thread_t *listener; - int child_num_arg; - apr_threadattr_t *threadattr; -} thread_starter; - -#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) - -/* - * The max child slot ever assigned, preserved across restarts. Necessary - * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We - * use this value to optimize routines that have to scan the entire - * scoreboard. - */ -int ap_max_daemons_limit = -1; - -static ap_pod_t *pod; - -/* *Non*-shared http_main globals... */ - -server_rec *ap_server_conf; - -/* The worker MPM respects a couple of runtime flags that can aid - * in debugging. Setting the -DNO_DETACH flag will prevent the root process - * from detaching from its controlling terminal. Additionally, setting - * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the - * child_main loop running in the process which originally started up. - * This gives you a pretty nice debugging environment. (You'll get a SIGHUP - * early in standalone_main; just continue through. This is the server - * trying to kill off any child processes which it might have lying - * around --- Apache doesn't keep track of their pids, it just sends - * SIGHUP to the process group, ignoring it in the root process. - * Continue through and you'll be fine.). - */ - -static int one_process = 0; - -#ifdef DEBUG_SIGSTOP -int raise_sigstop_flags; -#endif - -static apr_pool_t *pconf; /* Pool for config stuff */ -static apr_pool_t *pchild; /* Pool for httpd child stuff */ - -static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main - thread. Use this instead */ -static pid_t parent_pid; -static apr_os_thread_t *listener_os_thread; - -/* Locks for accept serialization */ -static apr_proc_mutex_t *accept_mutex; - -#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT -#define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS) -#else -#define SAFE_ACCEPT(stmt) (stmt) -#endif - -/* The LISTENER_SIGNAL signal will be sent from the main thread to the - * listener thread to wake it up for graceful termination (what a child - * process from an old generation does when the admin does "apachectl - * graceful"). This signal will be blocked in all threads of a child - * process except for the listener thread. - */ -#define LISTENER_SIGNAL SIGHUP - -/* An array of socket descriptors in use by each thread used to - * perform a non-graceful (forced) shutdown of the server. */ -static apr_socket_t **worker_sockets; - -static void close_worker_sockets(void) -{ - int i; - for (i = 0; i < ap_threads_per_child; i++) { - if (worker_sockets[i]) { - apr_socket_close(worker_sockets[i]); - worker_sockets[i] = NULL; - } - } -} - -static void wakeup_listener(void) -{ - listener_may_exit = 1; - if (!listener_os_thread) { - /* XXX there is an obscure path that this doesn't handle perfectly: - * right after listener thread is created but before - * listener_os_thread is set, the first worker thread hits an - * error and starts graceful termination - */ - return; - } - /* - * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all - * platforms and wake up the listener thread since it is the only thread - * with SIGHUP unblocked, but that doesn't work on Linux - */ -#ifdef HAVE_PTHREAD_KILL - pthread_kill(*listener_os_thread, LISTENER_SIGNAL); -#else - kill(ap_my_pid, LISTENER_SIGNAL); -#endif -} - -#define ST_INIT 0 -#define ST_GRACEFUL 1 -#define ST_UNGRACEFUL 2 - -static int terminate_mode = ST_INIT; - -static void signal_threads(int mode) -{ - if (terminate_mode == mode) { - return; - } - terminate_mode = mode; - mpm_state = AP_MPMQ_STOPPING; - - /* in case we weren't called from the listener thread, wake up the - * listener thread - */ - wakeup_listener(); - - /* for ungraceful termination, let the workers exit now; - * for graceful termination, the listener thread will notify the - * workers to exit once it has stopped accepting new connections - */ - if (mode == ST_UNGRACEFUL) { - workers_may_exit = 1; - ap_queue_interrupt_all(worker_queue); - ap_queue_info_term(worker_queue_info); - close_worker_sockets(); /* forcefully kill all current connections */ - } -} - -AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) -{ - switch(query_code){ - case AP_MPMQ_MAX_DAEMON_USED: - *result = ap_max_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_IS_THREADED: - *result = AP_MPMQ_STATIC; - return APR_SUCCESS; - case AP_MPMQ_IS_FORKED: - *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_DAEMONS: - *result = server_limit; - return APR_SUCCESS; - case AP_MPMQ_HARD_LIMIT_THREADS: - *result = thread_limit; - return APR_SUCCESS; - case AP_MPMQ_MAX_THREADS: - *result = ap_threads_per_child; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MIN_SPARE_THREADS: - *result = min_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_DAEMONS: - *result = 0; - return APR_SUCCESS; - case AP_MPMQ_MAX_SPARE_THREADS: - *result = max_spare_threads; - return APR_SUCCESS; - case AP_MPMQ_MAX_REQUESTS_DAEMON: - *result = ap_max_requests_per_child; - return APR_SUCCESS; - case AP_MPMQ_MAX_DAEMONS: - *result = ap_daemons_limit; - return APR_SUCCESS; - case AP_MPMQ_MPM_STATE: - *result = mpm_state; - return APR_SUCCESS; - } - return APR_ENOTIMPL; -} - -/* a clean exit from a child with proper cleanup */ -static void clean_child_exit(int code) __attribute__ ((noreturn)); -static void clean_child_exit(int code) -{ - mpm_state = AP_MPMQ_STOPPING; - if (pchild) { - apr_pool_destroy(pchild); - } - exit(code); -} - -static void just_die(int sig) -{ - clean_child_exit(0); -} - -/***************************************************************** - * Connection structures and accounting... - */ - -/* volatile just in case */ -static int volatile shutdown_pending; -static int volatile restart_pending; -static int volatile is_graceful; -static volatile int child_fatal; -ap_generation_t volatile ap_my_generation; - -/* - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at - * functions to initiate shutdown or restart without relying on signals. - * Previously this was initiated in sig_term() and restart() signal handlers, - * but we want to be able to start a shutdown/restart from other sources -- - * e.g. on Win32, from the service manager. Now the service manager can - * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that - * these functions can also be called by the child processes, since global - * variables are no longer used to pass on the required action to the parent. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. - */ - -static void ap_start_shutdown(void) -{ - mpm_state = AP_MPMQ_STOPPING; - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; -} - -/* do a graceful restart if graceful == 1 */ -static void ap_start_restart(int graceful) -{ - mpm_state = AP_MPMQ_STOPPING; - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - is_graceful = graceful; -} - -static void sig_term(int sig) -{ - ap_start_shutdown(); -} - -static void restart(int sig) -{ - ap_start_restart(sig == AP_SIG_GRACEFUL); -} - -static void set_signals(void) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; -#endif - - if (!one_process) { - ap_fatal_signal_setup(ap_server_conf, pconf); - } - -#ifndef NO_USE_SIGACTION - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGTERM)"); -#ifdef SIGINT - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGINT)"); -#endif -#ifdef SIGXCPU - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXCPU, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXCPU)"); -#endif -#ifdef SIGXFSZ - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXFSZ, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGXFSZ)"); -#endif -#ifdef SIGPIPE - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGPIPE)"); -#endif - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, - "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -#else - if (!one_process) { -#ifdef SIGXCPU - apr_signal(SIGXCPU, SIG_DFL); -#endif /* SIGXCPU */ -#ifdef SIGXFSZ - apr_signal(SIGXFSZ, SIG_DFL); -#endif /* SIGXFSZ */ - } - - apr_signal(SIGTERM, sig_term); -#ifdef SIGHUP - apr_signal(SIGHUP, restart); -#endif /* SIGHUP */ -#ifdef AP_SIG_GRACEFUL - apr_signal(AP_SIG_GRACEFUL, restart); -#endif /* AP_SIG_GRACEFUL */ -#ifdef SIGPIPE - apr_signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - -#endif -} - -/***************************************************************** - * Here follows a long bunch of generic server bookkeeping stuff... - */ - -int ap_graceful_stop_signalled(void) - /* XXX this is really a bad confusing obsolete name - * maybe it should be ap_mpm_process_exiting? - */ -{ - /* note: for a graceful termination, listener_may_exit will be set before - * workers_may_exit, so check listener_may_exit - */ - return listener_may_exit; -} - -/***************************************************************** - * Child process main loop. - */ - -static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, - int my_thread_num, apr_bucket_alloc_t *bucket_alloc) -{ - conn_rec *current_conn; - long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); - int csd; - ap_sb_handle_t *sbh; - - ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); - apr_os_sock_get(&csd, sock); - - current_conn = ap_run_create_connection(p, ap_server_conf, sock, - conn_id, sbh, bucket_alloc); - if (current_conn) { - ap_process_connection(current_conn, sock); - ap_lingering_close(current_conn); - } -} - -/* requests_this_child has gone to zero or below. See if the admin coded - "MaxRequestsPerChild 0", and keep going in that case. Doing it this way - simplifies the hot path in worker_thread */ -static void check_infinite_requests(void) -{ - if (ap_max_requests_per_child) { - signal_threads(ST_GRACEFUL); - } - else { - /* wow! if you're executing this code, you may have set a record. - * either this child process has served over 2 billion requests, or - * you're running a threaded 2.0 on a 16 bit machine. - * - * I'll buy pizza and beers at Apachecon for the first person to do - * the former without cheating (dorking with INT_MAX, or running with - * uncommitted performance patches, for example). - * - * for the latter case, you probably deserve a beer too. Greg Ames - */ - - requests_this_child = INT_MAX; /* keep going */ - } -} - -static void unblock_signal(int sig) -{ - sigset_t sig_mask; - - sigemptyset(&sig_mask); - sigaddset(&sig_mask, sig); -#if defined(SIGPROCMASK_SETS_THREAD_MASK) - sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); -#else - pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); -#endif -} - -static void dummy_signal_handler(int sig) -{ - /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall, - * then we don't need this goofy function. - */ -} - -static void *listener_thread(apr_thread_t *thd, void * dummy) -{ - proc_info * ti = dummy; - int process_slot = ti->pid; - apr_pool_t *tpool = apr_thread_pool_get(thd); - void *csd = NULL; - apr_pool_t *ptrans = NULL; /* Pool for per-transaction stuff */ - int n; - apr_pollfd_t *pollset; - apr_status_t rv; - ap_listen_rec *lr, *last_lr = ap_listeners; - int have_idle_worker = 0; - - free(ti); - - apr_poll_setup(&pollset, num_listensocks, tpool); - for(lr = ap_listeners ; lr != NULL ; lr = lr->next) - apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); - - /* Unblock the signal used to wake this thread up, and set a handler for - * it. - */ - unblock_signal(LISTENER_SIGNAL); - apr_signal(LISTENER_SIGNAL, dummy_signal_handler); - - /* TODO: Switch to a system where threads reuse the results from earlier - poll calls - manoj */ - while (1) { - /* TODO: requests_this_child should be synchronized - aaron */ - if (requests_this_child <= 0) { - check_infinite_requests(); - } - if (listener_may_exit) break; - - if (!have_idle_worker) { - /* the following pops a recycled ptrans pool off a stack - * if there is one, in addition to reserving a worker thread - */ - rv = ap_queue_info_wait_for_idler(worker_queue_info, - &ptrans); - if (APR_STATUS_IS_EOF(rv)) { - break; /* we've been signaled to die now */ - } - else if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_queue_info_wait failed. Attempting to " - " shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - break; - } - have_idle_worker = 1; - } - - /* We've already decremented the idle worker count inside - * ap_queue_info_wait_for_idler. */ - - if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (listener_may_exit) { - break; - } - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_lock failed. Attempting to shutdown " - "process gracefully."); - signal_threads(ST_GRACEFUL); - break; /* skip the lock release */ - } - - if (!ap_listeners->next) { - /* Only one listener, so skip the poll */ - lr = ap_listeners; - } - else { - while (!listener_may_exit) { - apr_status_t ret; - apr_int16_t event; - - ret = apr_poll(pollset, num_listensocks, &n, -1); - if (ret != APR_SUCCESS) { - if (APR_STATUS_IS_EINTR(ret)) { - continue; - } - - /* apr_pollset_poll() will only return errors in catastrophic - * circumstances. Let's try exiting gracefully, for now. */ - ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) - ap_server_conf, "apr_poll: (listen)"); - signal_threads(ST_GRACEFUL); - } - - if (listener_may_exit) break; - - /* find a listener */ - lr = last_lr; - do { - lr = lr->next; - if (lr == NULL) { - lr = ap_listeners; - } - /* XXX: Should we check for POLLERR? */ - apr_poll_revents_get(&event, lr->sd, pollset); - if (event & APR_POLLIN) { - last_lr = lr; - goto got_fd; - } - } while (lr != last_lr); - } - } - got_fd: - if (!listener_may_exit) { - if (ptrans == NULL) { - /* we can't use a recycled transaction pool this time. - * create a new transaction pool */ - apr_allocator_t *allocator; - - apr_allocator_create(&allocator); - apr_allocator_max_free_set(allocator, ap_max_mem_free); - apr_pool_create_ex(&ptrans, NULL, NULL, allocator); - apr_allocator_owner_set(allocator, ptrans); - } - apr_pool_tag(ptrans, "transaction"); - rv = lr->accept_func(&csd, lr, ptrans); - /* later we trash rv and rely on csd to indicate success/failure */ - AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd); - - if (rv == APR_EGENERAL) { - /* E[NM]FILE, ENOMEM, etc */ - resource_shortage = 1; - signal_threads(ST_GRACEFUL); - } - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (listener_may_exit) { - break; - } - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - } - if (csd != NULL) { - rv = ap_queue_push(worker_queue, csd, ptrans); - if (rv) { - /* trash the connection; we couldn't queue the connected - * socket to a worker - */ - apr_socket_close(csd); - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "ap_queue_push failed"); - } - else { - have_idle_worker = 0; - } - } - } - else { - if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) - != APR_SUCCESS) { - int level = APLOG_EMERG; - - if (ap_scoreboard_image->parent[process_slot].generation != - ap_scoreboard_image->global->running_generation) { - level = APLOG_DEBUG; /* common to get these at restart time */ - } - ap_log_error(APLOG_MARK, level, rv, ap_server_conf, - "apr_proc_mutex_unlock failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - } - break; - } - } - - ap_queue_term(worker_queue); - dying = 1; - ap_scoreboard_image->parent[process_slot].quiescing = 1; - - /* wake up the main thread */ - kill(ap_my_pid, SIGTERM); - - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -/* XXX For ungraceful termination/restart, we definitely don't want to - * wait for active connections to finish but we may want to wait - * for idle workers to get out of the queue code and release mutexes, - * since those mutexes are cleaned up pretty soon and some systems - * may not react favorably (i.e., segfault) if operations are attempted - * on cleaned-up mutexes. - */ -static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy) -{ - proc_info * ti = dummy; - int process_slot = ti->pid; - int thread_slot = ti->tid; - apr_socket_t *csd = NULL; - apr_bucket_alloc_t *bucket_alloc; - apr_pool_t *last_ptrans = NULL; - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - apr_status_t rv; - int is_idle = 0; - - free(ti); - - ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); - - while (!workers_may_exit) { - if (!is_idle) { - rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans); - last_ptrans = NULL; - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "ap_queue_info_set_idle failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - break; - } - is_idle = 1; - } - - ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); -worker_pop: - if (workers_may_exit) { - break; - } - rv = ap_queue_pop(worker_queue, &csd, &ptrans); - - if (rv != APR_SUCCESS) { - /* We get APR_EOF during a graceful shutdown once all the connections - * accepted by this server process have been handled. - */ - if (APR_STATUS_IS_EOF(rv)) { - break; - } - /* We get APR_EINTR whenever ap_queue_pop() has been interrupted - * from an explicit call to ap_queue_interrupt_all(). This allows - * us to unblock threads stuck in ap_queue_pop() when a shutdown - * is pending. - * - * If workers_may_exit is set and this is ungraceful termination/ - * restart, we are bound to get an error on some systems (e.g., - * AIX, which sanity-checks mutex operations) since the queue - * may have already been cleaned up. Don't log the "error" if - * workers_may_exit is set. - */ - else if (APR_STATUS_IS_EINTR(rv)) { - goto worker_pop; - } - /* We got some other error. */ - else if (!workers_may_exit) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "ap_queue_pop failed"); - } - continue; - } - is_idle = 0; - worker_sockets[thread_slot] = csd; - bucket_alloc = apr_bucket_alloc_create(ptrans); - process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc); - worker_sockets[thread_slot] = NULL; - requests_this_child--; /* FIXME: should be synchronized - aaron */ - apr_pool_clear(ptrans); - last_ptrans = ptrans; - } - - ap_update_child_status_from_indexes(process_slot, thread_slot, - (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); - - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -static int check_signal(int signum) -{ - switch (signum) { - case SIGTERM: - case SIGINT: - return 1; - } - return 0; -} - -static void create_listener_thread(thread_starter *ts) -{ - int my_child_num = ts->child_num_arg; - apr_threadattr_t *thread_attr = ts->threadattr; - proc_info *my_info; - apr_status_t rv; - - my_info = (proc_info *)malloc(sizeof(proc_info)); - my_info->pid = my_child_num; - my_info->tid = -1; /* listener thread doesn't have a thread slot */ - my_info->sd = 0; - rv = apr_thread_create(&ts->listener, thread_attr, listener_thread, - my_info, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create listener thread"); - /* let the parent decide how bad this really is */ - clean_child_exit(APEXIT_CHILDSICK); - } - apr_os_thread_get(&listener_os_thread, ts->listener); -} - -/* XXX under some circumstances not understood, children can get stuck - * in start_threads forever trying to take over slots which will - * never be cleaned up; for now there is an APLOG_DEBUG message issued - * every so often when this condition occurs - */ -static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) -{ - thread_starter *ts = dummy; - apr_thread_t **threads = ts->threads; - apr_threadattr_t *thread_attr = ts->threadattr; - int child_num_arg = ts->child_num_arg; - int my_child_num = child_num_arg; - proc_info *my_info; - apr_status_t rv; - int i; - int threads_created = 0; - int listener_started = 0; - int loops; - int prev_threads_created; - - /* We must create the fd queues before we start up the listener - * and worker threads. */ - worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue)); - rv = ap_queue_init(worker_queue, ap_threads_per_child, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "ap_queue_init() failed"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - rv = ap_queue_info_create(&worker_queue_info, pchild, - ap_threads_per_child); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "ap_queue_info_create() failed"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - worker_sockets = apr_pcalloc(pchild, ap_threads_per_child - * sizeof(apr_socket_t *)); - - loops = prev_threads_created = 0; - while (1) { - /* ap_threads_per_child does not include the listener thread */ - for (i = 0; i < ap_threads_per_child; i++) { - int status = ap_scoreboard_image->servers[child_num_arg][i].status; - - if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { - continue; - } - - my_info = (proc_info *)malloc(sizeof(proc_info)); - if (my_info == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - my_info->pid = my_child_num; - my_info->tid = i; - my_info->sd = 0; - - /* We are creating threads right now */ - ap_update_child_status_from_indexes(my_child_num, i, - SERVER_STARTING, NULL); - /* We let each thread update its own scoreboard entry. This is - * done because it lets us deal with tid better. - */ - rv = apr_thread_create(&threads[i], thread_attr, - worker_thread, my_info, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* let the parent decide how bad this really is */ - clean_child_exit(APEXIT_CHILDSICK); - } - threads_created++; - } - /* Start the listener only when there are workers available */ - if (!listener_started && threads_created) { - create_listener_thread(ts); - listener_started = 1; - } - if (start_thread_may_exit || threads_created == ap_threads_per_child) { - break; - } - /* wait for previous generation to clean up an entry */ - apr_sleep(apr_time_from_sec(1)); - ++loops; - if (loops % 120 == 0) { /* every couple of minutes */ - if (prev_threads_created == threads_created) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "child %" APR_PID_T_FMT " isn't taking over " - "slots very quickly (%d of %d)", - ap_my_pid, threads_created, ap_threads_per_child); - } - prev_threads_created = threads_created; - } - } - - /* What state should this child_main process be listed as in the - * scoreboard...? - * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, - * (request_rec *) NULL); - * - * This state should be listed separately in the scoreboard, in some kind - * of process_status, not mixed in with the worker threads' status. - * "life_status" is almost right, but it's in the worker's structure, and - * the name could be clearer. gla - */ - apr_thread_exit(thd, APR_SUCCESS); - return NULL; -} - -static void join_workers(apr_thread_t *listener, apr_thread_t **threads) -{ - int i; - apr_status_t rv, thread_rv; - - if (listener) { - int iter; - - /* deal with a rare timing window which affects waking up the - * listener thread... if the signal sent to the listener thread - * is delivered between the time it verifies that the - * listener_may_exit flag is clear and the time it enters a - * blocking syscall, the signal didn't do any good... work around - * that by sleeping briefly and sending it again - */ - - iter = 0; - while (iter < 10 && -#ifdef HAVE_PTHREAD_KILL - pthread_kill(*listener_os_thread, 0) -#else - kill(ap_my_pid, 0) -#endif - == 0) { - /* listener not dead yet */ - apr_sleep(apr_time_make(0, 500000)); - wakeup_listener(); - ++iter; - } - if (iter >= 10) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "the listener thread didn't exit"); - } - else { - rv = apr_thread_join(&thread_rv, listener); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join listener thread"); - } - } - } - - for (i = 0; i < ap_threads_per_child; i++) { - if (threads[i]) { /* if we ever created this thread */ - rv = apr_thread_join(&thread_rv, threads[i]); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join worker " - "thread %d", - i); - } - } - } -} - -static void join_start_thread(apr_thread_t *start_thread_id) -{ - apr_status_t rv, thread_rv; - - start_thread_may_exit = 1; /* tell it to give up in case it is still - * trying to take over slots from a - * previous generation - */ - rv = apr_thread_join(&thread_rv, start_thread_id); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "apr_thread_join: unable to join the start " - "thread"); - } -} - -static void child_main(int child_num_arg) -{ - apr_thread_t **threads; - apr_status_t rv; - thread_starter *ts; - apr_threadattr_t *thread_attr; - apr_thread_t *start_thread_id; - - mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this - * child initializes - */ - ap_my_pid = getpid(); - ap_fatal_signal_child_setup(ap_server_conf); - apr_pool_create(&pchild, pconf); - - /*stuff to do before we switch id's, so we have permissions.*/ - ap_reopen_scoreboard(pchild, NULL, 0); - - rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, - pchild)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize cross-process lock in child"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (unixd_setup_child()) { - clean_child_exit(APEXIT_CHILDFATAL); - } - - ap_run_child_init(pchild, ap_server_conf); - - /* done with init critical section */ - - /* Just use the standard apr_setup_signal_thread to block all signals - * from being received. The child processes no longer use signals for - * any communication with the parent process. - */ - rv = apr_setup_signal_thread(); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "Couldn't initialize signal thread"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - if (ap_max_requests_per_child) { - requests_this_child = ap_max_requests_per_child; - } - else { - /* coding a value of zero means infinity */ - requests_this_child = INT_MAX; - } - - /* Setup worker threads */ - - /* clear the storage; we may not create all our threads immediately, - * and we want a 0 entry to indicate a thread which was not created - */ - threads = (apr_thread_t **)calloc(1, - sizeof(apr_thread_t *) * ap_threads_per_child); - if (threads == NULL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, - "malloc: out of memory"); - clean_child_exit(APEXIT_CHILDFATAL); - } - - ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts)); - - apr_threadattr_create(&thread_attr, pchild); - /* 0 means PTHREAD_CREATE_JOINABLE */ - apr_threadattr_detach_set(thread_attr, 0); - - ts->threads = threads; - ts->listener = NULL; - ts->child_num_arg = child_num_arg; - ts->threadattr = thread_attr; - - rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, - ts, pchild); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, - "apr_thread_create: unable to create worker thread"); - /* let the parent decide how bad this really is */ - clean_child_exit(APEXIT_CHILDSICK); - } - - mpm_state = AP_MPMQ_RUNNING; - - /* If we are only running in one_process mode, we will want to - * still handle signals. */ - if (one_process) { - /* Block until we get a terminating signal. */ - apr_signal_thread(check_signal); - /* make sure the start thread has finished; signal_threads() - * and join_workers() depend on that - */ - /* XXX join_start_thread() won't be awakened if one of our - * threads encounters a critical error and attempts to - * shutdown this child - */ - join_start_thread(start_thread_id); - signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more - * quickly than the dispatch of the signal thread - * beats the Pipe of Death and the browsers - */ - /* A terminating signal was received. Now join each of the - * workers to clean them up. - * If the worker already exited, then the join frees - * their resources and returns. - * If the worker hasn't exited, then this blocks until - * they have (then cleans up). - */ - join_workers(ts->listener, threads); - } - else { /* !one_process */ - /* remove SIGTERM from the set of blocked signals... if one of - * the other threads in the process needs to take us down - * (e.g., for MaxRequestsPerChild) it will send us SIGTERM - */ - unblock_signal(SIGTERM); - apr_signal(SIGTERM, dummy_signal_handler); - /* Watch for any messages from the parent over the POD */ - while (1) { - rv = ap_mpm_pod_check(pod); - if (rv == AP_NORESTART) { - /* see if termination was triggered while we slept */ - switch(terminate_mode) { - case ST_GRACEFUL: - rv = AP_GRACEFUL; - break; - case ST_UNGRACEFUL: - rv = AP_RESTART; - break; - } - } - if (rv == AP_GRACEFUL || rv == AP_RESTART) { - /* make sure the start thread has finished; - * signal_threads() and join_workers depend on that - */ - join_start_thread(start_thread_id); - signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); - break; - } - } - - /* A terminating signal was received. Now join each of the - * workers to clean them up. - * If the worker already exited, then the join frees - * their resources and returns. - * If the worker hasn't exited, then this blocks until - * they have (then cleans up). - */ - join_workers(ts->listener, threads); - } - - free(threads); - - clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); -} - -static int make_child(server_rec *s, int slot) -{ - int pid; - - if (slot + 1 > ap_max_daemons_limit) { - ap_max_daemons_limit = slot + 1; - } - - if (one_process) { - set_signals(); - ap_scoreboard_image->parent[slot].pid = getpid(); - child_main(slot); - } - - if ((pid = fork()) == -1) { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, - "fork: Unable to fork new process"); - - /* fork didn't succeed. Fix the scoreboard or else - * it will say SERVER_STARTING forever and ever - */ - ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); - - /* In case system resources are maxxed out, we don't want - Apache running away with the CPU trying to fork over and - over and over again. */ - apr_sleep(apr_time_from_sec(10)); - - return -1; - } - - if (!pid) { -#ifdef HAVE_BINDPROCESSOR - /* By default, AIX binds to a single processor. This bit unbinds - * children which will then bind to another CPU. - */ - int status = bindprocessor(BINDPROCESS, (int)getpid(), - PROCESSOR_CLASS_ANY); - if (status != OK) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, - ap_server_conf, - "processor unbind failed %d", status); -#endif - RAISE_SIGSTOP(MAKE_CHILD); - - apr_signal(SIGTERM, just_die); - child_main(slot); - - clean_child_exit(0); - } - /* else */ - if (ap_scoreboard_image->parent[slot].pid != 0) { - /* This new child process is squatting on the scoreboard - * entry owned by an exiting child process, which cannot - * exit until all active requests complete. - * Don't forget about this exiting child process, or we - * won't be able to kill it if it doesn't exit by the - * time the server is shut down. - */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "taking over scoreboard slot from %" APR_PID_T_FMT "%s", - ap_scoreboard_image->parent[slot].pid, - ap_scoreboard_image->parent[slot].quiescing ? - " (quiescing)" : ""); - ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid); - } - ap_scoreboard_image->parent[slot].quiescing = 0; - ap_scoreboard_image->parent[slot].pid = pid; - return 0; -} - -/* start up a bunch of children */ -static void startup_children(int number_to_start) -{ - int i; - - for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->parent[i].pid != 0) { - continue; - } - if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; - } -} - - -/* - * idle_spawn_rate is the number of children that will be spawned on the - * next maintenance cycle if there aren't enough idle servers. It is - * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by - * without the need to spawn. - */ -static int idle_spawn_rate = 1; -#ifndef MAX_SPAWN_RATE -#define MAX_SPAWN_RATE (32) -#endif -static int hold_off_on_exponential_spawning; - -static void perform_idle_server_maintenance(void) -{ - int i, j; - int idle_thread_count; - worker_score *ws; - process_score *ps; - int free_length; - int totally_free_length = 0; - int free_slots[MAX_SPAWN_RATE]; - int last_non_dead; - int total_non_dead; - int active_thread_count = 0; - - /* initialize the free_list */ - free_length = 0; - - idle_thread_count = 0; - last_non_dead = -1; - total_non_dead = 0; - - for (i = 0; i < ap_daemons_limit; ++i) { - /* Initialization to satisfy the compiler. It doesn't know - * that ap_threads_per_child is always > 0 */ - int status = SERVER_DEAD; - int any_dying_threads = 0; - int any_dead_threads = 0; - int all_dead_threads = 1; - - if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate) - break; - ps = &ap_scoreboard_image->parent[i]; - for (j = 0; j < ap_threads_per_child; j++) { - ws = &ap_scoreboard_image->servers[i][j]; - status = ws->status; - - /* XXX any_dying_threads is probably no longer needed GLA */ - any_dying_threads = any_dying_threads || - (status == SERVER_GRACEFUL); - any_dead_threads = any_dead_threads || (status == SERVER_DEAD); - all_dead_threads = all_dead_threads && - (status == SERVER_DEAD || - status == SERVER_GRACEFUL); - - /* We consider a starting server as idle because we started it - * at least a cycle ago, and if it still hasn't finished starting - * then we're just going to swamp things worse by forking more. - * So we hopefully won't need to fork more if we count it. - * This depends on the ordering of SERVER_READY and SERVER_STARTING. - */ - if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for - loop if no pid? not much else matters */ - if (status <= SERVER_READY && status != SERVER_DEAD && - !ps->quiescing && - ps->generation == ap_my_generation) { - ++idle_thread_count; - } - if (status >= SERVER_READY && status < SERVER_GRACEFUL) { - ++active_thread_count; - } - } - } - if (any_dead_threads && totally_free_length < idle_spawn_rate - && free_length < MAX_SPAWN_RATE - && (!ps->pid /* no process in the slot */ - || ps->quiescing)) { /* or at least one is going away */ - if (all_dead_threads) { - /* great! we prefer these, because the new process can - * start more threads sooner. So prioritize this slot - * by putting it ahead of any slots with active threads. - * - * first, make room by moving a slot that's potentially still - * in use to the end of the array - */ - free_slots[free_length] = free_slots[totally_free_length]; - free_slots[totally_free_length++] = i; - } - else { - /* slot is still in use - back of the bus - */ - free_slots[free_length] = i; - } - ++free_length; - } - /* XXX if (!ps->quiescing) is probably more reliable GLA */ - if (!any_dying_threads) { - last_non_dead = i; - ++total_non_dead; - } - } - - if (sick_child_detected) { - if (active_thread_count > 0) { - /* some child processes appear to be working. don't kill the - * whole server. - */ - sick_child_detected = 0; - } - else { - /* looks like a basket case. give up. - */ - shutdown_pending = 1; - child_fatal = 1; - ap_log_error(APLOG_MARK, APLOG_ALERT, 0, - ap_server_conf, - "No active workers found..." - " Apache is exiting!"); - /* the child already logged the failure details */ - return; - } - } - - ap_max_daemons_limit = last_non_dead + 1; - - if (idle_thread_count > max_spare_threads) { - /* Kill off one child */ - ap_mpm_pod_signal(pod, TRUE); - idle_spawn_rate = 1; - } - else if (idle_thread_count < min_spare_threads) { - /* terminate the free list */ - if (free_length == 0) { - /* only report this condition once */ - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, - ap_server_conf, - "server reached MaxClients setting, consider" - " raising the MaxClients setting"); - reported = 1; - } - idle_spawn_rate = 1; - } - else { - if (free_length > idle_spawn_rate) { - free_length = idle_spawn_rate; - } - if (idle_spawn_rate >= 8) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "server seems busy, (you may need " - "to increase StartServers, ThreadsPerChild " - "or Min/MaxSpareThreads), " - "spawning %d children, there are around %d idle " - "threads, and %d total children", free_length, - idle_thread_count, total_non_dead); - } - for (i = 0; i < free_length; ++i) { - make_child(ap_server_conf, free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful - */ - if (hold_off_on_exponential_spawning) { - --hold_off_on_exponential_spawning; - } - else if (idle_spawn_rate < MAX_SPAWN_RATE) { - idle_spawn_rate *= 2; - } - } - } - else { - idle_spawn_rate = 1; - } -} - -static void server_main_loop(int remaining_children_to_start) -{ - int child_slot; - apr_exit_why_e exitwhy; - int status, processed_status; - apr_proc_t pid; - int i; - - while (!restart_pending && !shutdown_pending) { - ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); - - if (pid.pid != -1) { - processed_status = ap_process_child_status(&pid, exitwhy, status); - if (processed_status == APEXIT_CHILDFATAL) { - shutdown_pending = 1; - child_fatal = 1; - return; - } - else if (processed_status == APEXIT_CHILDSICK) { - /* tell perform_idle_server_maintenance to check into this - * on the next timer pop - */ - sick_child_detected = 1; - } - /* non-fatal death... note that it's gone in the scoreboard. */ - child_slot = find_child_by_pid(&pid); - if (child_slot >= 0) { - for (i = 0; i < ap_threads_per_child; i++) - ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); - - ap_scoreboard_image->parent[child_slot].pid = 0; - ap_scoreboard_image->parent[child_slot].quiescing = 0; - if (processed_status == APEXIT_CHILDSICK) { - /* resource shortage, minimize the fork rate */ - idle_spawn_rate = 1; - } - else if (remaining_children_to_start - && child_slot < ap_daemons_limit) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - make_child(ap_server_conf, child_slot); - --remaining_children_to_start; - } - } - else if (ap_unregister_extra_mpm_process(pid.pid) == 1) { - /* handled */ -#if APR_HAS_OTHER_CHILD - } - else if (apr_proc_other_child_read(&pid, status) == 0) { - /* handled */ -#endif - } - else if (is_graceful) { - /* Great, we've probably just lost a slot in the - * scoreboard. Somehow we don't know about this child. - */ - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, - ap_server_conf, - "long lost child came home! (pid %ld)", - (long)pid.pid); - } - /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ - continue; - } - else if (remaining_children_to_start) { - /* we hit a 1 second timeout in which none of the previous - * generation of children needed to be reaped... so assume - * they're all done, and pick up the slack if any is left. - */ - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - /* In any event we really shouldn't do the code below because - * few of the servers we just started are in the IDLE state - * yet, so we'd mistakenly create an extra server. - */ - continue; - } - - perform_idle_server_maintenance(); - } -} - -int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) -{ - int remaining_children_to_start; - apr_status_t rv; - - ap_log_pid(pconf, ap_pid_fname); - - first_server_limit = server_limit; - first_thread_limit = thread_limit; - if (changed_limit_at_restart) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - "WARNING: Attempt to change ServerLimit or ThreadLimit " - "ignored during restart"); - changed_limit_at_restart = 0; - } - - /* Initialize cross-process accept lock */ - ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, - ap_server_root_relative(_pconf, ap_lock_fname), - ap_my_pid); - - rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, - ap_accept_lock_mech, _pconf); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't create accept lock"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - -#if APR_USE_SYSVSEM_SERIALIZE - if (ap_accept_lock_mech == APR_LOCK_DEFAULT || - ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#else - if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { -#endif - rv = unixd_set_proc_mutex_perms(accept_mutex); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, - "Couldn't set permissions on cross-process lock; " - "check User and Group directives"); - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - } - - if (!is_graceful) { - if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - mpm_state = AP_MPMQ_STOPPING; - return 1; - } - /* fix the generation number in the global score; we just got a new, - * cleared scoreboard - */ - ap_scoreboard_image->global->running_generation = ap_my_generation; - } - - set_signals(); - /* Don't thrash... */ - if (max_spare_threads < min_spare_threads + ap_threads_per_child) - max_spare_threads = min_spare_threads + ap_threads_per_child; - - /* If we're doing a graceful_restart then we're going to see a lot - * of children exiting immediately when we get into the main loop - * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty - * rapidly... and for each one that exits we'll start a new one until - * we reach at least daemons_min_free. But we may be permitted to - * start more than that, so we'll just keep track of how many we're - * supposed to start up without the 1 second penalty between each fork. - */ - remaining_children_to_start = ap_daemons_to_start; - if (remaining_children_to_start > ap_daemons_limit) { - remaining_children_to_start = ap_daemons_limit; - } - if (!is_graceful) { - startup_children(remaining_children_to_start); - remaining_children_to_start = 0; - } - else { - /* give the system some time to recover before kicking into - * exponential mode */ - hold_off_on_exponential_spawning = 10; - } - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "%s configured -- resuming normal operations", - ap_get_server_version()); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, - "Server built: %s", ap_get_server_built()); -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "AcceptMutex: %s (default: %s)", - apr_proc_mutex_name(accept_mutex), - apr_proc_mutex_defname()); -#endif - restart_pending = shutdown_pending = 0; - mpm_state = AP_MPMQ_RUNNING; - - server_main_loop(remaining_children_to_start); - mpm_state = AP_MPMQ_STOPPING; - - if (shutdown_pending) { - /* Time to gracefully shut down: - * Kill child processes, tell them to call child_exit, etc... - * (By "gracefully" we don't mean graceful in the same sense as - * "apachectl graceful" where we allow old connections to finish.) - */ - ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - - if (!child_fatal) { - /* cleanup pid file on normal shutdown */ - const char *pidfile = NULL; - pidfile = ap_server_root_relative (pconf, ap_pid_fname); - if ( pidfile != NULL && unlink(pidfile) == 0) - ap_log_error(APLOG_MARK, APLOG_INFO, 0, - ap_server_conf, - "removed PID file %s (pid=%ld)", - pidfile, (long)getpid()); - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, - ap_server_conf, "caught SIGTERM, shutting down"); - } - return 1; - } - - /* we've been told to restart */ - apr_signal(SIGHUP, SIG_IGN); - - if (one_process) { - /* not worth thinking about */ - return 1; - } - - /* advance to the next generation */ - /* XXX: we really need to make sure this new generation number isn't in - * use by any of the children. - */ - ++ap_my_generation; - ap_scoreboard_image->global->running_generation = ap_my_generation; - - if (is_graceful) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); - /* wake up the children...time to die. But we'll have more soon */ - ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE); - - - /* This is mostly for debugging... so that we know what is still - * gracefully dealing with existing request. - */ - - } - else { - /* Kill 'em all. Since the child acts the same on the parents SIGTERM - * and a SIGHUP, we may as well use the same signal, because some user - * pthreads are stealing signals from us left and right. - */ - ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); - - ap_reclaim_child_processes(1); /* Start with SIGTERM */ - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "SIGHUP received. Attempting to restart"); - } - - return 0; -} - -/* This really should be a post_config hook, but the error log is already - * redirected by that point, so we need to do this in the open_logs phase. - */ -static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) -{ - apr_status_t rv; - - pconf = p; - ap_server_conf = s; - - if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, - NULL, "no listening sockets available, shutting down"); - return DONE; - } - - if (!one_process) { - if ((rv = ap_mpm_pod_open(pconf, &pod))) { - ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, - "Could not open pipe-of-death."); - return DONE; - } - } - return OK; -} - -static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp) -{ - static int restart_num = 0; - int no_detach, debug, foreground; - ap_directive_t *pdir; - ap_directive_t *max_clients = NULL; - apr_status_t rv; - - mpm_state = AP_MPMQ_STARTING; - - /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ - for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { - if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { - if (!max_clients) { - break; /* we're in the clear, got ThreadsPerChild first */ - } - else { - /* now to swap the data */ - ap_directive_t temp; - - temp.directive = pdir->directive; - temp.args = pdir->args; - /* Make sure you don't change 'next', or you may get loops! */ - /* XXX: first_child, parent, and data can never be set - * for these directives, right? -aaron */ - temp.filename = pdir->filename; - temp.line_num = pdir->line_num; - - pdir->directive = max_clients->directive; - pdir->args = max_clients->args; - pdir->filename = max_clients->filename; - pdir->line_num = max_clients->line_num; - - max_clients->directive = temp.directive; - max_clients->args = temp.args; - max_clients->filename = temp.filename; - max_clients->line_num = temp.line_num; - break; - } - } - else if (!max_clients - && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { - max_clients = pdir; - } - } - - debug = ap_exists_config_define("DEBUG"); - - if (debug) { - foreground = one_process = 1; - no_detach = 0; - } - else { - one_process = ap_exists_config_define("ONE_PROCESS"); - no_detach = ap_exists_config_define("NO_DETACH"); - foreground = ap_exists_config_define("FOREGROUND"); - } - - /* sigh, want this only the second time around */ - if (restart_num++ == 1) { - is_graceful = 0; - - if (!one_process && !foreground) { - rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND - : APR_PROC_DETACH_DAEMONIZE); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "apr_proc_detach failed"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - parent_pid = ap_my_pid = getpid(); - } - - unixd_pre_config(ptemp); - ap_listen_pre_config(); - ap_daemons_to_start = DEFAULT_START_DAEMON; - min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; - max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; - ap_daemons_limit = server_limit; - ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; - ap_pid_fname = DEFAULT_PIDLOG; - ap_lock_fname = DEFAULT_LOCKFILE; - ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE - ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; -#endif - - apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); - - return OK; -} - -static void worker_hooks(apr_pool_t *p) -{ - /* The worker open_logs phase must run before the core's, or stderr - * will be redirected to a file, and the messages won't print to the - * console. - */ - static const char *const aszSucc[] = {"core.c", NULL}; - one_process = 0; - - ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); - /* we need to set the MPM state before other pre-config hooks use MPM query - * to retrieve it, so register as REALLY_FIRST - */ - ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); -} - -static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_daemons_to_start = atoi(arg); - return NULL; -} - -static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - min_spare_threads = atoi(arg); - if (min_spare_threads <= 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: detected MinSpareThreads set to non-positive."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Resetting to 1 to avoid almost certain Apache failure."); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Please read the documentation."); - min_spare_threads = 1; - } - - return NULL; -} - -static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - max_spare_threads = atoi(arg); - return NULL; -} - -static const char *set_max_clients (cmd_parms *cmd, void *dummy, - const char *arg) -{ - int max_clients; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - /* It is ok to use ap_threads_per_child here because we are - * sure that it gets set before MaxClients in the pre_config stage. */ - max_clients = atoi(arg); - if (max_clients < ap_threads_per_child) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients (%d) must be at least as large", - max_clients); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " as ThreadsPerChild (%d). Automatically", - ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " increasing MaxClients to %d.", - ap_threads_per_child); - max_clients = ap_threads_per_child; - } - ap_daemons_limit = max_clients / ap_threads_per_child; - if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients (%d) is not an integer multiple", - max_clients); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " of ThreadsPerChild (%d), lowering MaxClients to %d", - ap_threads_per_child, - ap_daemons_limit * ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " for a maximum of %d child processes,", - ap_daemons_limit); - max_clients = ap_daemons_limit * ap_threads_per_child; - } - if (ap_daemons_limit > server_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: MaxClients of %d would require %d servers,", - max_clients, ap_daemons_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " and would exceed the ServerLimit value of %d.", - server_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " Automatically lowering MaxClients to %d. To increase,", - server_limit * ap_threads_per_child); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " please see the ServerLimit directive."); - ap_daemons_limit = server_limit; - } - else if (ap_daemons_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require MaxClients > 0, setting to 1"); - ap_daemons_limit = 1; - } - return NULL; -} - -static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_threads_per_child = atoi(arg); - if (ap_threads_per_child > thread_limit) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " - "value of %d", ap_threads_per_child, - thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "threads, lowering ThreadsPerChild to %d. To increase, please" - " see the", thread_limit); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " ThreadLimit directive."); - ap_threads_per_child = thread_limit; - } - else if (ap_threads_per_child < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadsPerChild > 0, setting to 1"); - ap_threads_per_child = 1; - } - return NULL; -} - -static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_server_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_server_limit = atoi(arg); - /* you cannot change ServerLimit across a restart; ignore - * any such attempts - */ - if (first_server_limit && - tmp_server_limit != server_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - server_limit = tmp_server_limit; - - if (server_limit > MAX_SERVER_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ServerLimit of %d exceeds compile time limit " - "of %d servers,", server_limit, MAX_SERVER_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); - server_limit = MAX_SERVER_LIMIT; - } - else if (server_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ServerLimit > 0, setting to 1"); - server_limit = 1; - } - return NULL; -} - -static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) -{ - int tmp_thread_limit; - - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - tmp_thread_limit = atoi(arg); - /* you cannot change ThreadLimit across a restart; ignore - * any such attempts - */ - if (first_thread_limit && - tmp_thread_limit != thread_limit) { - /* how do we log a message? the error log is a bit bucket at this - * point; we'll just have to set a flag so that ap_mpm_run() - * logs a warning later - */ - changed_limit_at_restart = 1; - return NULL; - } - thread_limit = tmp_thread_limit; - - if (thread_limit > MAX_THREAD_LIMIT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: ThreadLimit of %d exceeds compile time limit " - "of %d servers,", thread_limit, MAX_THREAD_LIMIT); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); - thread_limit = MAX_THREAD_LIMIT; - } - else if (thread_limit < 1) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "WARNING: Require ThreadLimit > 0, setting to 1"); - thread_limit = 1; - } - return NULL; -} - -static const command_rec worker_cmds[] = { -UNIX_DAEMON_COMMANDS, -LISTEN_COMMANDS, -AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, - "Number of child processes launched at server startup"), -AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, - "Minimum number of idle threads, to handle request spikes"), -AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, - "Maximum number of idle threads"), -AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, - "Maximum number of threads alive at the same time"), -AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, - "Number of threads each child creates"), -AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, - "Maximum number of child processes for this run of Apache"), -AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, - "Maximum number of worker threads per child process for this run of Apache - Upper limit for ThreadsPerChild"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA mpm_worker_module = { - MPM20_MODULE_STUFF, - ap_mpm_rewrite_args, /* hook to run before apache parses args */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - worker_cmds, /* command apr_table_t */ - worker_hooks /* register_hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.lo b/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.lo deleted file mode 100644 index 83f3b7ff..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.lo +++ /dev/null @@ -1,12 +0,0 @@ -# worker.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/worker.o' - -# Name of the non-PIC object. -non_pic_object='worker.o' - diff --git a/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.o b/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.o Binary files differdeleted file mode 100644 index dc560c2b..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm/worker/worker.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/mpm_common.c b/rubbos/app/httpd-2.0.64/server/mpm_common.c deleted file mode 100644 index 3a961ff0..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm_common.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The purpose of this file is to store the code that MOST mpm's will need - * this does not mean a function only goes into this file if every MPM needs - * it. It means that if a function is needed by more than one MPM, and - * future maintenance would be served by making the code common, then the - * function belongs here. - * - * This is going in src/main because it is not platform specific, it is - * specific to multi-process servers, but NOT to Unix. Which is why it - * does not belong in src/os/unix - */ - -#include "apr.h" -#include "apr_thread_proc.h" -#include "apr_signal.h" -#include "apr_strings.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" -#include "apr_getopt.h" -#include "apr_optional.h" -#include "apr_allocator.h" - -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "http_main.h" -#include "mpm.h" -#include "mpm_common.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "mpm_default.h" - -#ifdef AP_MPM_WANT_SET_SCOREBOARD -#include "scoreboard.h" -#endif - -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif -#ifdef HAVE_GRP_H -#include <grp.h> -#endif -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES - -typedef enum {DO_NOTHING, SEND_SIGTERM, SEND_SIGKILL, GIVEUP} action_t; - -typedef struct extra_process_t { - struct extra_process_t *next; - pid_t pid; -} extra_process_t; - -static extra_process_t *extras; - -void ap_register_extra_mpm_process(pid_t pid) -{ - extra_process_t *p = (extra_process_t *)malloc(sizeof(extra_process_t)); - - p->next = extras; - p->pid = pid; - extras = p; -} - -int ap_unregister_extra_mpm_process(pid_t pid) -{ - extra_process_t *cur = extras; - extra_process_t *prev = NULL; - - while (cur && cur->pid != pid) { - prev = cur; - cur = cur->next; - } - - if (cur) { - if (prev) { - prev->next = cur->next; - } - else { - extras = cur->next; - } - free(cur); - return 1; /* found */ - } - else { - /* we don't know about any such process */ - return 0; - } -} - -static int reclaim_one_pid(pid_t pid, action_t action) -{ - apr_proc_t proc; - apr_status_t waitret; - - /* Ensure pid sanity. */ - if (pid < 1) { - return 1; - } - - proc.pid = pid; - waitret = apr_proc_wait(&proc, NULL, NULL, APR_NOWAIT); - if (waitret != APR_CHILD_NOTDONE) { - return 1; - } - - switch(action) { - case DO_NOTHING: - break; - - case SEND_SIGTERM: - /* ok, now it's being annoying */ - ap_log_error(APLOG_MARK, APLOG_WARNING, - 0, ap_server_conf, - "child process %" APR_PID_T_FMT - " still did not exit, " - "sending a SIGTERM", - pid); - kill(pid, SIGTERM); - break; - - case SEND_SIGKILL: - ap_log_error(APLOG_MARK, APLOG_ERR, - 0, ap_server_conf, - "child process %" APR_PID_T_FMT - " still did not exit, " - "sending a SIGKILL", - pid); -#ifndef BEOS - kill(pid, SIGKILL); -#else - /* sending a SIGKILL kills the entire team on BeOS, and as - * httpd thread is part of that team it removes any chance - * of ever doing a restart. To counter this I'm changing to - * use a kinder, gentler way of killing a specific thread - * that is just as effective. - */ - kill_thread(pid); -#endif - break; - - case GIVEUP: - /* gave it our best shot, but alas... If this really - * is a child we are trying to kill and it really hasn't - * exited, we will likely fail to bind to the port - * after the restart. - */ - ap_log_error(APLOG_MARK, APLOG_ERR, - 0, ap_server_conf, - "could not make child process %" APR_PID_T_FMT - " exit, " - "attempting to continue anyway", - pid); - break; - } - - return 0; -} - -void ap_reclaim_child_processes(int terminate) -{ - apr_time_t waittime = 1024 * 16; - int i; - extra_process_t *cur_extra; - int not_dead_yet; - int max_daemons; - apr_time_t starttime = apr_time_now(); - /* this table of actions and elapsed times tells what action is taken - * at which elapsed time from starting the reclaim - */ - struct { - action_t action; - apr_time_t action_time; - } action_table[] = { - {DO_NOTHING, 0}, /* dummy entry for iterations where we reap - * children but take no action against - * stragglers - */ - {SEND_SIGTERM, apr_time_from_sec(3)}, - {SEND_SIGTERM, apr_time_from_sec(5)}, - {SEND_SIGTERM, apr_time_from_sec(7)}, - {SEND_SIGKILL, apr_time_from_sec(9)}, - {GIVEUP, apr_time_from_sec(10)} - }; - int cur_action; /* index of action we decided to take this - * iteration - */ - int next_action = 1; /* index of first real action */ - - ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons); - - do { - apr_sleep(waittime); - /* don't let waittime get longer than 1 second; otherwise, we don't - * react quickly to the last child exiting, and taking action can - * be delayed - */ - waittime = waittime * 4; - if (waittime > apr_time_from_sec(1)) { - waittime = apr_time_from_sec(1); - } - - /* see what action to take, if any */ - if (action_table[next_action].action_time <= apr_time_now() - starttime) { - cur_action = next_action; - ++next_action; - } - else { - cur_action = 0; /* nothing to do */ - } - - /* now see who is done */ - not_dead_yet = 0; - for (i = 0; i < max_daemons; ++i) { - pid_t pid = MPM_CHILD_PID(i); - - if (pid == 0) { - continue; /* not every scoreboard entry is in use */ - } - - if (reclaim_one_pid(pid, action_table[cur_action].action)) { - MPM_NOTE_CHILD_KILLED(i); - } - else { - ++not_dead_yet; - } - } - - cur_extra = extras; - while (cur_extra) { - extra_process_t *next = cur_extra->next; - - if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) { - AP_DEBUG_ASSERT(1 == ap_unregister_extra_mpm_process(cur_extra->pid)); - } - else { - ++not_dead_yet; - } - cur_extra = next; - } - -#if APR_HAS_OTHER_CHILD - apr_proc_other_child_check(); -#endif - - } while (not_dead_yet > 0 && - action_table[cur_action].action != GIVEUP); -} -#endif /* AP_MPM_WANT_RECLAIM_CHILD_PROCESSES */ - -#ifdef AP_MPM_WANT_WAIT_OR_TIMEOUT - -/* number of calls to wait_or_timeout between writable probes */ -#ifndef INTERVAL_OF_WRITABLE_PROBES -#define INTERVAL_OF_WRITABLE_PROBES 10 -#endif -static int wait_or_timeout_counter; - -void ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret, - apr_pool_t *p) -{ - apr_status_t rv; - - ++wait_or_timeout_counter; - if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) { - wait_or_timeout_counter = 0; - } - - rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p); - if (APR_STATUS_IS_EINTR(rv)) { - ret->pid = -1; - return; - } - - if (APR_STATUS_IS_CHILD_DONE(rv)) { - return; - } - -#ifdef NEED_WAITPID - if ((ret = reap_children(exitcode, status)) > 0) { - return; - } -#endif - - apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); - ret->pid = -1; - return; -} -#endif /* AP_MPM_WANT_WAIT_OR_TIMEOUT */ - -#ifdef AP_MPM_WANT_PROCESS_CHILD_STATUS -int ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status) -{ - int signum = status; - const char *sigdesc = apr_signal_description_get(signum); - - /* Child died... if it died due to a fatal error, - * we should simply bail out. The caller needs to - * check for bad rc from us and exit, running any - * appropriate cleanups. - * - * If the child died due to a resource shortage, - * the parent should limit the rate of forking - */ - if (APR_PROC_CHECK_EXIT(why)) { - if (status == APEXIT_CHILDSICK) { - return status; - } - - if (status == APEXIT_CHILDFATAL) { - ap_log_error(APLOG_MARK, APLOG_ALERT, - 0, ap_server_conf, - "Child %" APR_PID_T_FMT - " returned a Fatal error... Apache is exiting!", - pid->pid); - return APEXIT_CHILDFATAL; - } - - return 0; - } - - if (APR_PROC_CHECK_SIGNALED(why)) { - switch (signum) { - case SIGTERM: - case SIGHUP: - case AP_SIG_GRACEFUL: - case SIGKILL: - break; - - default: - if (APR_PROC_CHECK_CORE_DUMP(why)) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "child pid %ld exit signal %s (%d), " - "possible coredump in %s", - (long)pid->pid, sigdesc, signum, - ap_coredump_dir); - } - else { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "child pid %ld exit signal %s (%d)", - (long)pid->pid, sigdesc, signum); - } - } - } - return 0; -} -#endif /* AP_MPM_WANT_PROCESS_CHILD_STATUS */ - -#if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF) -void ap_sock_disable_nagle(apr_socket_t *s) -{ - /* The Nagle algorithm says that we should delay sending partial - * packets in hopes of getting more data. We don't want to do - * this; we are not telnet. There are bad interactions between - * persistent connections and Nagle's algorithm that have very severe - * performance penalties. (Failing to disable Nagle is not much of a - * problem with simple HTTP.) - * - * In spite of these problems, failure here is not a shooting offense. - */ - apr_status_t status = apr_socket_opt_set(s, APR_TCP_NODELAY, 1); - - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, status, ap_server_conf, - "apr_socket_opt_set: (TCP_NODELAY)"); - } -} -#endif - -#ifdef HAVE_GETPWNAM -AP_DECLARE(uid_t) ap_uname2id(const char *name) -{ - struct passwd *ent; - - if (name[0] == '#') - return (atoi(&name[1])); - - if (!(ent = getpwnam(name))) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s: bad user name %s", ap_server_argv0, name); - exit(1); - } - - return (ent->pw_uid); -} -#endif - -#ifdef HAVE_GETGRNAM -AP_DECLARE(gid_t) ap_gname2id(const char *name) -{ - struct group *ent; - - if (name[0] == '#') - return (atoi(&name[1])); - - if (!(ent = getgrnam(name))) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s: bad group name %s", ap_server_argv0, name); - exit(1); - } - - return (ent->gr_gid); -} -#endif - -#ifndef HAVE_INITGROUPS -int initgroups(const char *name, gid_t basegid) -{ -#if defined(QNX) || defined(MPE) || defined(BEOS) || defined(_OSD_POSIX) || defined(TPF) || defined(__TANDEM) || defined(OS2) || defined(WIN32) || defined(NETWARE) -/* QNX, MPE and BeOS do not appear to support supplementary groups. */ - return 0; -#else /* ndef QNX */ - gid_t groups[NGROUPS_MAX]; - struct group *g; - int index = 0; - - setgrent(); - - groups[index++] = basegid; - - while (index < NGROUPS_MAX && ((g = getgrent()) != NULL)) { - if (g->gr_gid != basegid) { - char **names; - - for (names = g->gr_mem; *names != NULL; ++names) { - if (!strcmp(*names, name)) - groups[index++] = g->gr_gid; - } - } - } - - endgrent(); - - return setgroups(index, groups); -#endif /* def QNX */ -} -#endif /* def NEED_INITGROUPS */ - -#ifdef AP_MPM_USES_POD - -AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod) -{ - apr_status_t rv; - - *pod = apr_palloc(p, sizeof(**pod)); - rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); - if (rv != APR_SUCCESS) { - return rv; - } - - apr_file_pipe_timeout_set((*pod)->pod_in, 0); - (*pod)->p = p; - - /* close these before exec. */ - apr_file_unset_inherit((*pod)->pod_in); - apr_file_unset_inherit((*pod)->pod_out); - - return APR_SUCCESS; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_check(ap_pod_t *pod) -{ - char c; - apr_size_t len = 1; - apr_status_t rv; - - rv = apr_file_read(pod->pod_in, &c, &len); - - if ((rv == APR_SUCCESS) && (len == 1)) { - return APR_SUCCESS; - } - - if (rv != APR_SUCCESS) { - return rv; - } - - return AP_NORESTART; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod) -{ - apr_status_t rv; - - rv = apr_file_close(pod->pod_out); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_file_close(pod->pod_in); - if (rv != APR_SUCCESS) { - return rv; - } - - return APR_SUCCESS; -} - -static apr_status_t pod_signal_internal(ap_pod_t *pod) -{ - apr_status_t rv; - char char_of_death = '!'; - apr_size_t one = 1; - - rv = apr_file_write(pod->pod_out, &char_of_death, &one); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, - "write pipe_of_death"); - } - - return rv; -} - -/* This function connects to the server, then immediately closes the connection. - * This permits the MPM to skip the poll when there is only one listening - * socket, because it provides a alternate way to unblock an accept() when - * the pod is used. - */ -static apr_status_t dummy_connection(ap_pod_t *pod) -{ - apr_status_t rv; - apr_socket_t *sock; - apr_pool_t *p; - - /* create a temporary pool for the socket. pconf stays around too long */ - rv = apr_pool_create(&p, pod->p); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_socket_create(&sock, ap_listeners->bind_addr->family, SOCK_STREAM, p); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, - "get socket to connect to listener"); - return rv; - } - - /* on some platforms (e.g., FreeBSD), the kernel won't accept many - * queued connections before it starts blocking local connects... - * we need to keep from blocking too long and instead return an error, - * because the MPM won't want to hold up a graceful restart for a - * long time - */ - rv = apr_socket_timeout_set(sock, apr_time_from_sec(3)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, - "set timeout on socket to connect to listener"); - apr_socket_close(sock); - return rv; - } - - rv = apr_connect(sock, ap_listeners->bind_addr); - if (rv != APR_SUCCESS) { - int log_level = APLOG_WARNING; - - if (APR_STATUS_IS_TIMEUP(rv)) { - /* probably some server processes bailed out already and there - * is nobody around to call accept and clear out the kernel - * connection queue; usually this is not worth logging - */ - log_level = APLOG_DEBUG; - } - - ap_log_error(APLOG_MARK, log_level, rv, ap_server_conf, - "connect to listener on %pI", ap_listeners->bind_addr); - } - - apr_socket_close(sock); - apr_pool_destroy(p); - - return rv; -} - -AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod) -{ - apr_status_t rv; - - rv = pod_signal_internal(pod); - if (rv != APR_SUCCESS) { - return rv; - } - - return dummy_connection(pod); -} - -void ap_mpm_pod_killpg(ap_pod_t *pod, int num) -{ - int i; - apr_status_t rv = APR_SUCCESS; - - /* we don't write anything to the pod here... we assume - * that the would-be reader of the pod has another way to - * see that it is time to die once we wake it up - * - * writing lots of things to the pod at once is very - * problematic... we can fill the kernel pipe buffer and - * be blocked until somebody consumes some bytes or - * we hit a timeout... if we hit a timeout we can't just - * keep trying because maybe we'll never successfully - * write again... but then maybe we'll leave would-be - * readers stranded (a number of them could be tied up for - * a while serving time-consuming requests) - */ - for (i = 0; i < num && rv == APR_SUCCESS; i++) { - rv = dummy_connection(pod); - } -} -#endif /* #ifdef AP_MPM_USES_POD */ - -/* standard mpm configuration handling */ -#ifdef AP_MPM_WANT_SET_PIDFILE -const char *ap_pid_fname = NULL; - -const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - if (cmd->server->is_virtual) { - return "PidFile directive not allowed in <VirtualHost>"; - } - - ap_pid_fname = arg; - return NULL; -} -#endif - -#ifdef AP_MPM_WANT_SET_SCOREBOARD -const char * ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_scoreboard_fname = arg; - return NULL; -} -#endif - -#ifdef AP_MPM_WANT_SET_LOCKFILE -const char *ap_lock_fname = NULL; - -const char *ap_mpm_set_lockfile(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_lock_fname = arg; - return NULL; -} -#endif - -#ifdef AP_MPM_WANT_SET_MAX_REQUESTS -int ap_max_requests_per_child = 0; - -const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_max_requests_per_child = atoi(arg); - - return NULL; -} -#endif - -#ifdef AP_MPM_WANT_SET_COREDUMPDIR -char ap_coredump_dir[MAX_STRING_LEN]; -int ap_coredumpdir_configured; - -const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy, - const char *arg) -{ - apr_status_t rv; - apr_finfo_t finfo; - const char *fname; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - fname = ap_server_root_relative(cmd->pool, arg); - if (!fname) { - return apr_pstrcat(cmd->pool, "Invalid CoreDumpDirectory path ", - arg, NULL); - } - if ((rv = apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool)) != APR_SUCCESS) { - return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, - " does not exist", NULL); - } - if (finfo.filetype != APR_DIR) { - return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, - " is not a directory", NULL); - } - apr_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir)); - ap_coredumpdir_configured = 1; - return NULL; -} -#endif - -#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -apr_lockmech_e ap_accept_lock_mech = APR_LOCK_DEFAULT; - -const char ap_valid_accept_mutex_string[] = - "Valid accept mutexes for this platform and MPM are: default" -#if APR_HAS_FLOCK_SERIALIZE - ", flock" -#endif -#if APR_HAS_FCNTL_SERIALIZE - ", fcntl" -#endif -#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) - ", sysvsem" -#endif -#if APR_HAS_POSIXSEM_SERIALIZE - ", posixsem" -#endif -#if APR_HAS_PROC_PTHREAD_SERIALIZE - ", pthread" -#endif - "."; - -AP_DECLARE(const char *) ap_mpm_set_accept_lock_mech(cmd_parms *cmd, - void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - if (!strcasecmp(arg, "default")) { - ap_accept_lock_mech = APR_LOCK_DEFAULT; - } -#if APR_HAS_FLOCK_SERIALIZE - else if (!strcasecmp(arg, "flock")) { - ap_accept_lock_mech = APR_LOCK_FLOCK; - } -#endif -#if APR_HAS_FCNTL_SERIALIZE - else if (!strcasecmp(arg, "fcntl")) { - ap_accept_lock_mech = APR_LOCK_FCNTL; - } -#endif - - /* perchild can't use SysV sems because the permissions on the accept - * mutex can't be set to allow all processes to use the mutex and - * at the same time keep all users from being able to dink with the - * mutex - */ -#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) - else if (!strcasecmp(arg, "sysvsem")) { - ap_accept_lock_mech = APR_LOCK_SYSVSEM; - } -#endif -#if APR_HAS_POSIXSEM_SERIALIZE - else if (!strcasecmp(arg, "posixsem")) { - ap_accept_lock_mech = APR_LOCK_POSIXSEM; - } -#endif -#if APR_HAS_PROC_PTHREAD_SERIALIZE - else if (!strcasecmp(arg, "pthread")) { - ap_accept_lock_mech = APR_LOCK_PROC_PTHREAD; - } -#endif - else { - return apr_pstrcat(cmd->pool, arg, " is an invalid mutex mechanism; ", - ap_valid_accept_mutex_string, NULL); - } - return NULL; -} - -#endif - -#ifdef AP_MPM_WANT_SIGNAL_SERVER - -static const char *dash_k_arg; - -static int send_signal(pid_t pid, int sig) -{ - if (kill(pid, sig) < 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, errno, NULL, - "sending signal to server"); - return 1; - } - return 0; -} - -int ap_signal_server(int *exit_status, apr_pool_t *pconf) -{ - apr_status_t rv; - pid_t otherpid; - int running = 0; - int have_pid_file = 0; - const char *status; - - *exit_status = 0; - - rv = ap_read_pid(pconf, ap_pid_fname, &otherpid); - if (rv != APR_SUCCESS) { - if (rv != APR_ENOENT) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL, - "Error retrieving pid file %s", ap_pid_fname); - *exit_status = 1; - return 1; - } - status = "httpd (no pid file) not running"; - } - else { - have_pid_file = 1; - if (kill(otherpid, 0) == 0) { - running = 1; - status = apr_psprintf(pconf, - "httpd (pid %" APR_PID_T_FMT ") already " - "running", otherpid); - } - else { - status = apr_psprintf(pconf, - "httpd (pid %" APR_PID_T_FMT "?) not running", - otherpid); - } - } - - if (!strcmp(dash_k_arg, "start")) { - if (running) { - printf("%s\n", status); - return 1; - } - } - - if (!strcmp(dash_k_arg, "stop")) { - if (!running) { - printf("%s\n", status); - } - else { - send_signal(otherpid, SIGTERM); - } - return 1; - } - - if (!strcmp(dash_k_arg, "restart")) { - if (!running) { - printf("httpd not running, trying to start\n"); - } - else { - *exit_status = send_signal(otherpid, SIGHUP); - return 1; - } - } - - if (!strcmp(dash_k_arg, "graceful")) { - if (!running) { - printf("httpd not running, trying to start\n"); - } - else { - *exit_status = send_signal(otherpid, SIGUSR1); - return 1; - } - } - - return 0; -} - -void ap_mpm_rewrite_args(process_rec *process) -{ - apr_array_header_t *mpm_new_argv; - apr_status_t rv; - apr_getopt_t *opt; - char optbuf[3]; - const char *optarg; - int fixed_args; - - mpm_new_argv = apr_array_make(process->pool, process->argc, - sizeof(const char **)); - *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; - fixed_args = mpm_new_argv->nelts; - apr_getopt_init(&opt, process->pool, process->argc, process->argv); - opt->errfn = NULL; - optbuf[0] = '-'; - /* option char returned by apr_getopt() will be stored in optbuf[1] */ - optbuf[2] = '\0'; - while ((rv = apr_getopt(opt, "k:" AP_SERVER_BASEARGS, - optbuf + 1, &optarg)) == APR_SUCCESS) { - switch(optbuf[1]) { - case 'k': - if (!dash_k_arg) { - if (!strcmp(optarg, "start") || !strcmp(optarg, "stop") || - !strcmp(optarg, "restart") || !strcmp(optarg, "graceful")) { - dash_k_arg = optarg; - break; - } - } - default: - *(const char **)apr_array_push(mpm_new_argv) = - apr_pstrdup(process->pool, optbuf); - if (optarg) { - *(const char **)apr_array_push(mpm_new_argv) = optarg; - } - } - } - - /* back up to capture the bad argument */ - if (rv == APR_BADCH || rv == APR_BADARG) { - opt->ind--; - } - - while (opt->ind < opt->argc) { - *(const char **)apr_array_push(mpm_new_argv) = - apr_pstrdup(process->pool, opt->argv[opt->ind++]); - } - - process->argc = mpm_new_argv->nelts; - process->argv = (const char * const *)mpm_new_argv->elts; - - if (dash_k_arg) { - APR_REGISTER_OPTIONAL_FN(ap_signal_server); - } -} - -#endif /* AP_MPM_WANT_SIGNAL_SERVER */ - -#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE -apr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; - -const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, - const char *arg) -{ - long value; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - value = strtol(arg, NULL, 0); - if (value < 0 || errno == ERANGE) - return apr_pstrcat(cmd->pool, "Invalid MaxMemFree value: ", - arg, NULL); - - ap_max_mem_free = (apr_uint32_t)value * 1024; - - return NULL; -} - -#endif /* AP_MPM_WANT_SET_MAX_MEM_FREE */ - -#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER - -static pid_t parent_pid, my_pid; -apr_pool_t *pconf; - -#if AP_ENABLE_EXCEPTION_HOOK - -static int exception_hook_enabled; - -const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy, - const char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - if (cmd->server->is_virtual) { - return "EnableExceptionHook directive not allowed in <VirtualHost>"; - } - - if (strcasecmp(arg, "on") == 0) { - exception_hook_enabled = 1; - } - else if (strcasecmp(arg, "off") == 0) { - exception_hook_enabled = 0; - } - else { - return "parameter must be 'on' or 'off'"; - } - - return NULL; -} - -APR_HOOK_STRUCT( - APR_HOOK_LINK(fatal_exception) -) - -AP_IMPLEMENT_HOOK_RUN_ALL(int, fatal_exception, - (ap_exception_info_t *ei), (ei), OK, DECLINED) - -static void run_fatal_exception_hook(int sig) -{ - ap_exception_info_t ei = {0}; - - if (exception_hook_enabled && - geteuid() != 0 && - my_pid != parent_pid) { - ei.sig = sig; - ei.pid = my_pid; - ap_run_fatal_exception(&ei); - } -} -#endif /* AP_ENABLE_EXCEPTION_HOOK */ - -/* handle all varieties of core dumping signals */ -static void sig_coredump(int sig) -{ - apr_filepath_set(ap_coredump_dir, pconf); - apr_signal(sig, SIG_DFL); -#if AP_ENABLE_EXCEPTION_HOOK - run_fatal_exception_hook(sig); -#endif - /* linuxthreads issue calling getpid() here: - * This comparison won't match if the crashing thread is - * some module's thread that runs in the parent process. - * The fallout, which is limited to linuxthreads: - * The special log message won't be written when such a - * thread in the parent causes the parent to crash. - */ - if (getpid() == parent_pid) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, - 0, ap_server_conf, - "seg fault or similar nasty error detected " - "in the parent process"); - /* XXX we can probably add some rudimentary cleanup code here, - * like getting rid of the pid file. If any additional bad stuff - * happens, we are protected from recursive errors taking down the - * system since this function is no longer the signal handler GLA - */ - } - kill(getpid(), sig); - /* At this point we've got sig blocked, because we're still inside - * the signal handler. When we leave the signal handler it will - * be unblocked, and we'll take the signal... and coredump or whatever - * is appropriate for this particular Unix. In addition the parent - * will see the real signal we received -- whereas if we called - * abort() here, the parent would only see SIGABRT. - */ -} - -apr_status_t ap_fatal_signal_child_setup(server_rec *s) -{ - my_pid = getpid(); - return APR_SUCCESS; -} - -apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *in_pconf) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; - - sigemptyset(&sa.sa_mask); - -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#else - sa.sa_flags = 0; -#endif - - sa.sa_handler = sig_coredump; - if (sigaction(SIGSEGV, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGSEGV)"); -#ifdef SIGBUS - if (sigaction(SIGBUS, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGBUS)"); -#endif -#ifdef SIGABORT - if (sigaction(SIGABORT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABORT)"); -#endif -#ifdef SIGABRT - if (sigaction(SIGABRT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABRT)"); -#endif -#ifdef SIGILL - if (sigaction(SIGILL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGILL)"); -#endif - -#else /* NO_USE_SIGACTION */ - - apr_signal(SIGSEGV, sig_coredump); -#ifdef SIGBUS - apr_signal(SIGBUS, sig_coredump); -#endif /* SIGBUS */ -#ifdef SIGABORT - apr_signal(SIGABORT, sig_coredump); -#endif /* SIGABORT */ -#ifdef SIGABRT - apr_signal(SIGABRT, sig_coredump); -#endif /* SIGABRT */ -#ifdef SIGILL - apr_signal(SIGILL, sig_coredump); -#endif /* SIGILL */ - -#endif /* NO_USE_SIGACTION */ - - pconf = in_pconf; - parent_pid = my_pid = getpid(); - - return APR_SUCCESS; -} - -#endif /* AP_MPM_WANT_FATAL_SIGNAL_HANDLER */ diff --git a/rubbos/app/httpd-2.0.64/server/mpm_common.lo b/rubbos/app/httpd-2.0.64/server/mpm_common.lo deleted file mode 100644 index ba20abe1..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm_common.lo +++ /dev/null @@ -1,12 +0,0 @@ -# mpm_common.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/mpm_common.o' - -# Name of the non-PIC object. -non_pic_object='mpm_common.o' - diff --git a/rubbos/app/httpd-2.0.64/server/mpm_common.o b/rubbos/app/httpd-2.0.64/server/mpm_common.o Binary files differdeleted file mode 100644 index cd06b1d5..00000000 --- a/rubbos/app/httpd-2.0.64/server/mpm_common.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/protocol.c b/rubbos/app/httpd-2.0.64/server/protocol.c deleted file mode 100644 index 1e624f3d..00000000 --- a/rubbos/app/httpd-2.0.64/server/protocol.c +++ /dev/null @@ -1,1573 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * http_protocol.c --- routines which directly communicate with the client. - * - * Code originally by Rob McCool; much redone by Robert S. Thau - * and the Apache Software Foundation. - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_buckets.h" -#include "apr_lib.h" -#include "apr_signal.h" -#include "apr_strmatch.h" - -#define APR_WANT_STDIO /* for sscanf */ -#define APR_WANT_STRFUNC -#define APR_WANT_MEMFUNC -#include "apr_want.h" - -#define CORE_PRIVATE -#include "util_filter.h" -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_main.h" -#include "http_request.h" -#include "http_vhost.h" -#include "http_log.h" /* For errors detected in basic auth common - * support code... */ -#include "mod_core.h" -#include "util_charset.h" -#include "util_ebcdic.h" -#include "scoreboard.h" - -#if APR_HAVE_STDARG_H -#include <stdarg.h> -#endif -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - - -APR_HOOK_STRUCT( - APR_HOOK_LINK(post_read_request) - APR_HOOK_LINK(log_transaction) - APR_HOOK_LINK(http_method) - APR_HOOK_LINK(default_port) -) - -AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL; - - -/* Patterns to match in ap_make_content_type() */ -static const char *needcset[] = { - "text/plain", - "text/html", - NULL -}; -static const apr_strmatch_pattern **needcset_patterns; -static const apr_strmatch_pattern *charset_pattern; - -AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool) -{ - int i; - for (i = 0; needcset[i]; i++) { - continue; - } - needcset_patterns = (const apr_strmatch_pattern **) - apr_palloc(pool, (i + 1) * sizeof(apr_strmatch_pattern *)); - for (i = 0; needcset[i]; i++) { - needcset_patterns[i] = apr_strmatch_precompile(pool, needcset[i], 0); - } - needcset_patterns[i] = NULL; - charset_pattern = apr_strmatch_precompile(pool, "charset=", 0); -} - -/* - * Builds the content-type that should be sent to the client from the - * content-type specified. The following rules are followed: - * - if type is NULL, type is set to ap_default_type(r) - * - if charset adding is disabled, stop processing and return type. - * - then, if there are no parameters on type, add the default charset - * - return type - */ -AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type) -{ - const apr_strmatch_pattern **pcset; - core_dir_config *conf = - (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - core_request_config *request_conf; - apr_size_t type_len; - - if (!type) { - type = ap_default_type(r); - } - - if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) { - return type; - } - - request_conf = - ap_get_module_config(r->request_config, &core_module); - if (request_conf->suppress_charset) { - return type; - } - - type_len = strlen(type); - - if (apr_strmatch(charset_pattern, type, type_len) != NULL) { - /* already has parameter, do nothing */ - /* XXX we don't check the validity */ - ; - } - else { - /* see if it makes sense to add the charset. At present, - * we only add it if the Content-type is one of needcset[] - */ - for (pcset = needcset_patterns; *pcset ; pcset++) { - if (apr_strmatch(*pcset, type, type_len) != NULL) { - struct iovec concat[3]; - concat[0].iov_base = (void *)type; - concat[0].iov_len = type_len; - concat[1].iov_base = (void *)"; charset="; - concat[1].iov_len = sizeof("; charset=") - 1; - concat[2].iov_base = (void *)(conf->add_default_charset_name); - concat[2].iov_len = strlen(conf->add_default_charset_name); - type = apr_pstrcatv(r->pool, concat, 3, NULL); - break; - } - } - } - - return type; -} - -AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t clength) -{ - r->clength = clength; - apr_table_setn(r->headers_out, "Content-Length", - apr_off_t_toa(r->pool, clength)); -} - -/* - * Return the latest rational time from a request/mtime (modification time) - * pair. We return the mtime unless it's in the future, in which case we - * return the current time. We use the request time as a reference in order - * to limit the number of calls to time(). We don't check for futurosity - * unless the mtime is at least as new as the reference. - */ -AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime) -{ - apr_time_t now; - - /* For all static responses, it's almost certain that the file was - * last modified before the beginning of the request. So there's - * no reason to call time(NULL) again. But if the response has been - * created on demand, then it might be newer than the time the request - * started. In this event we really have to call time(NULL) again - * so that we can give the clients the most accurate Last-Modified. If we - * were given a time in the future, we return the current time - the - * Last-Modified can't be in the future. - */ - now = (mtime < r->request_time) ? r->request_time : apr_time_now(); - return (mtime > now) ? now : mtime; -} - -/* Min # of bytes to allocate when reading a request line */ -#define MIN_LINE_ALLOC 80 - -/* Get a line of protocol input, including any continuation lines - * caused by MIME folding (or broken clients) if fold != 0, and place it - * in the buffer s, of size n bytes, without the ending newline. - * - * If s is NULL, ap_rgetline_core will allocate necessary memory from r->pool. - * - * Returns APR_SUCCESS if there are no problems and sets *read to be - * the full length of s. - * - * APR_ENOSPC is returned if there is not enough buffer space. - * Other errors may be returned on other errors. - * - * The LF is *not* returned in the buffer. Therefore, a *read of 0 - * indicates that an empty line was read. - * - * Notes: Because the buffer uses 1 char for NUL, the most we can return is - * (n - 1) actual characters. - * - * If no LF is detected on the last line due to a dropped connection - * or a full buffer, that's considered an error. - */ -AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, - apr_size_t *read, request_rec *r, - int fold, apr_bucket_brigade *bb) -{ - apr_status_t rv; - apr_bucket *e; - apr_size_t bytes_handled = 0, current_alloc = 0; - char *pos, *last_char = *s; - int do_alloc = (*s == NULL), saw_eos = 0; - - /* - * Initialize last_char as otherwise a random value will be compared - * against APR_ASCII_LF at the end of the loop if bb only contains - * zero-length buckets. - */ - if (last_char) - *last_char = '\0'; - - for (;;) { - apr_brigade_cleanup(bb); - rv = ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE, - APR_BLOCK_READ, 0); - - if (rv != APR_SUCCESS) { - return rv; - } - - /* Something horribly wrong happened. Someone didn't block! */ - if (APR_BRIGADE_EMPTY(bb)) { - return APR_EGENERAL; - } - - APR_BRIGADE_FOREACH(e, bb) { - const char *str; - apr_size_t len; - - /* If we see an EOS, don't bother doing anything more. */ - if (APR_BUCKET_IS_EOS(e)) { - saw_eos = 1; - break; - } - - rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); - - if (rv != APR_SUCCESS) { - return rv; - } - - if (len == 0) { - /* no use attempting a zero-byte alloc (hurts when - * using --with-efence --enable-pool-debug) or - * doing any of the other logic either - */ - continue; - } - - /* Would this overrun our buffer? If so, we'll die. */ - if (n < bytes_handled + len) { - *read = bytes_handled; - if (*s) { - /* ensure this string is NUL terminated */ - if (bytes_handled > 0) { - (*s)[bytes_handled-1] = '\0'; - } - else { - (*s)[0] = '\0'; - } - } - return APR_ENOSPC; - } - - /* Do we have to handle the allocation ourselves? */ - if (do_alloc) { - /* We'll assume the common case where one bucket is enough. */ - if (!*s) { - current_alloc = len; - if (current_alloc < MIN_LINE_ALLOC) { - current_alloc = MIN_LINE_ALLOC; - } - *s = apr_palloc(r->pool, current_alloc); - } - else if (bytes_handled + len > current_alloc) { - /* Increase the buffer size */ - apr_size_t new_size = current_alloc * 2; - char *new_buffer; - - if (bytes_handled + len > new_size) { - new_size = (bytes_handled + len) * 2; - } - - new_buffer = apr_palloc(r->pool, new_size); - - /* Copy what we already had. */ - memcpy(new_buffer, *s, bytes_handled); - current_alloc = new_size; - *s = new_buffer; - } - } - - /* Just copy the rest of the data to the end of the old buffer. */ - pos = *s + bytes_handled; - memcpy(pos, str, len); - last_char = pos + len - 1; - - /* We've now processed that new data - update accordingly. */ - bytes_handled += len; - } - - /* If we got a full line of input, stop reading */ - if (last_char && (*last_char == APR_ASCII_LF)) { - break; - } - } - - /* Now NUL-terminate the string at the end of the line; - * if the last-but-one character is a CR, terminate there */ - if (last_char > *s && last_char[-1] == APR_ASCII_CR) { - last_char--; - } - *last_char = '\0'; - bytes_handled = last_char - *s; - - /* If we're folding, we have more work to do. - * - * Note that if an EOS was seen, we know we can't have another line. - */ - if (fold && bytes_handled && !saw_eos) { - for (;;) { - const char *str; - apr_size_t len; - char c; - - /* Clear the temp brigade for this filter read. */ - apr_brigade_cleanup(bb); - - /* We only care about the first byte. */ - rv = ap_get_brigade(r->input_filters, bb, AP_MODE_SPECULATIVE, - APR_BLOCK_READ, 1); - - if (rv != APR_SUCCESS) { - return rv; - } - - if (APR_BRIGADE_EMPTY(bb)) { - break; - } - - e = APR_BRIGADE_FIRST(bb); - - /* If we see an EOS, don't bother doing anything more. */ - if (APR_BUCKET_IS_EOS(e)) { - break; - } - - rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); - - if (rv != APR_SUCCESS) { - apr_brigade_cleanup(bb); - return rv; - } - - /* Found one, so call ourselves again to get the next line. - * - * FIXME: If the folding line is completely blank, should we - * stop folding? Does that require also looking at the next - * char? - */ - /* When we call destroy, the buckets are deleted, so save that - * one character we need. This simplifies our execution paths - * at the cost of one character read. - */ - c = *str; - if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) { - /* Do we have enough space? We may be full now. */ - if (bytes_handled >= n) { - *read = n; - /* ensure this string is terminated */ - (*s)[n-1] = '\0'; - return APR_ENOSPC; - } - else { - apr_size_t next_size, next_len; - char *tmp; - - /* If we're doing the allocations for them, we have to - * give ourselves a NULL and copy it on return. - */ - if (do_alloc) { - tmp = NULL; - } else { - /* We're null terminated. */ - tmp = last_char; - } - - next_size = n - bytes_handled; - - rv = ap_rgetline_core(&tmp, next_size, - &next_len, r, 0, bb); - - if (rv != APR_SUCCESS) { - return rv; - } - - if (do_alloc && next_len > 0) { - char *new_buffer; - apr_size_t new_size = bytes_handled + next_len + 1; - - /* we need to alloc an extra byte for a null */ - new_buffer = apr_palloc(r->pool, new_size); - - /* Copy what we already had. */ - memcpy(new_buffer, *s, bytes_handled); - - /* copy the new line, including the trailing null */ - memcpy(new_buffer + bytes_handled, tmp, next_len + 1); - *s = new_buffer; - } - - bytes_handled += next_len; - } - } - else { /* next character is not tab or space */ - break; - } - } - } - - *read = bytes_handled; - return APR_SUCCESS; -} - -#if APR_CHARSET_EBCDIC -AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n, - apr_size_t *read, request_rec *r, - int fold, apr_bucket_brigade *bb) -{ - /* on ASCII boxes, ap_rgetline is a macro which simply invokes - * ap_rgetline_core with the same parms - * - * on EBCDIC boxes, each complete http protocol input line needs to be - * translated into the code page used by the compiler. Since - * ap_rgetline_core uses recursion, we do the translation in a wrapper - * function to insure that each input character gets translated only once. - */ - apr_status_t rv; - - rv = ap_rgetline_core(s, n, read, r, fold, bb); - if (rv == APR_SUCCESS) { - ap_xlate_proto_from_ascii(*s, *read); - } - return rv; -} -#endif - -AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold) -{ - char *tmp_s = s; - apr_status_t rv; - apr_size_t len; - apr_bucket_brigade *tmp_bb; - - tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - rv = ap_rgetline(&tmp_s, n, &len, r, fold, tmp_bb); - apr_brigade_destroy(tmp_bb); - - /* Map the out-of-space condition to the old API. */ - if (rv == APR_ENOSPC) { - return n; - } - - /* Anything else is just bad. */ - if (rv != APR_SUCCESS) { - return -1; - } - - return (int)len; -} - -/* parse_uri: break apart the uri - * Side Effects: - * - sets r->args to rest after '?' (or NULL if no '?') - * - sets r->uri to request uri (without r->args part) - * - sets r->hostname (if not set already) from request (scheme://host:port) - */ -AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri) -{ - int status = HTTP_OK; - - r->unparsed_uri = apr_pstrdup(r->pool, uri); - - if (r->method_number == M_CONNECT) { - status = apr_uri_parse_hostinfo(r->pool, uri, &r->parsed_uri); - } - else { - /* Simple syntax Errors in URLs are trapped by - * parse_uri_components(). - */ - status = apr_uri_parse(r->pool, uri, &r->parsed_uri); - } - - if (status == APR_SUCCESS) { - /* if it has a scheme we may need to do absoluteURI vhost stuff */ - if (r->parsed_uri.scheme - && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) { - r->hostname = r->parsed_uri.hostname; - } - else if (r->method_number == M_CONNECT) { - r->hostname = r->parsed_uri.hostname; - } - - r->args = r->parsed_uri.query; - r->uri = r->parsed_uri.path ? r->parsed_uri.path - : apr_pstrdup(r->pool, "/"); - -#if defined(OS2) || defined(WIN32) - /* Handle path translations for OS/2 and plug security hole. - * This will prevent "http://www.wherever.com/..\..\/" from - * returning a directory for the root drive. - */ - { - char *x; - - for (x = r->uri; (x = strchr(x, '\\')) != NULL; ) - *x = '/'; - } -#endif /* OS2 || WIN32 */ - } - else { - r->args = NULL; - r->hostname = NULL; - r->status = HTTP_BAD_REQUEST; /* set error status */ - r->uri = apr_pstrdup(r->pool, uri); - } -} - -static int read_request_line(request_rec *r, apr_bucket_brigade *bb) -{ - const char *ll; - const char *uri; - const char *pro; - -#if 0 - conn_rec *conn = r->connection; -#endif - int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */ - char http[5]; - apr_size_t len; - int num_blank_lines = 0; - int max_blank_lines = r->server->limit_req_fields; - - if (max_blank_lines <= 0) { - max_blank_lines = DEFAULT_LIMIT_REQUEST_FIELDS; - } - - /* Read past empty lines until we get a real request line, - * a read error, the connection closes (EOF), or we timeout. - * - * We skip empty lines because browsers have to tack a CRLF on to the end - * of POSTs to support old CERN webservers. But note that we may not - * have flushed any previous response completely to the client yet. - * We delay the flush as long as possible so that we can improve - * performance for clients that are pipelining requests. If a request - * is pipelined then we won't block during the (implicit) read() below. - * If the requests aren't pipelined, then the client is still waiting - * for the final buffer flush from us, and we will block in the implicit - * read(). B_SAFEREAD ensures that the BUFF layer flushes if it will - * have to block during a read. - */ - - do { - apr_status_t rv; - - /* insure ap_rgetline allocates memory each time thru the loop - * if there are empty lines - */ - r->the_request = NULL; - rv = ap_rgetline(&(r->the_request), (apr_size_t)(r->server->limit_req_line + 2), - &len, r, 0, bb); - - if (rv != APR_SUCCESS) { - r->request_time = apr_time_now(); - - /* ap_rgetline returns APR_ENOSPC if it fills up the - * buffer before finding the end-of-line. This is only going to - * happen if it exceeds the configured limit for a request-line. - */ - if (rv == APR_ENOSPC) { - r->status = HTTP_REQUEST_URI_TOO_LARGE; - r->proto_num = HTTP_VERSION(1,0); - r->protocol = apr_pstrdup(r->pool, "HTTP/1.0"); - } - - return 0; - } - } while ((len <= 0) && (++num_blank_lines < max_blank_lines)); - - /* we've probably got something to do, ignore graceful restart requests */ - - r->request_time = apr_time_now(); - ll = r->the_request; - r->method = ap_getword_white(r->pool, &ll); - -#if 0 -/* XXX If we want to keep track of the Method, the protocol module should do - * it. That support isn't in the scoreboard yet. Hopefully next week - * sometime. rbb */ - ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", - r->method); -#endif - - uri = ap_getword_white(r->pool, &ll); - - /* Provide quick information about the request method as soon as known */ - - r->method_number = ap_method_number_of(r->method); - if (r->method_number == M_GET && r->method[0] == 'H') { - r->header_only = 1; - } - - ap_parse_uri(r, uri); - - if (ll[0]) { - r->assbackwards = 0; - pro = ll; - len = strlen(ll); - } else { - r->assbackwards = 1; - pro = "HTTP/0.9"; - len = 8; - } - r->protocol = apr_pstrmemdup(r->pool, pro, len); - - /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */ - - /* Avoid sscanf in the common case */ - if (len == 8 - && pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' - && pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' - && apr_isdigit(pro[7])) { - r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0'); - } - else if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor) - && (strcasecmp("http", http) == 0) - && (minor < HTTP_VERSION(1, 0)) ) /* don't allow HTTP/0.1000 */ - r->proto_num = HTTP_VERSION(major, minor); - else - r->proto_num = HTTP_VERSION(1, 0); - - return 1; -} - -AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb) -{ - char *last_field = NULL; - apr_size_t last_len = 0; - apr_size_t alloc_len = 0; - char *field; - char *value; - apr_size_t len; - int fields_read = 0; - char *tmp_field; - - /* - * Read header lines until we get the empty separator line, a read error, - * the connection closes (EOF), reach the server limit, or we timeout. - */ - while(1) { - apr_status_t rv; - int folded = 0; - - field = NULL; - rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2, - &len, r, 0, bb); - - /* ap_rgetline returns APR_ENOSPC if it fills up the buffer before - * finding the end-of-line. This is only going to happen if it - * exceeds the configured limit for a field size. - */ - if (rv == APR_ENOSPC && field) { - r->status = HTTP_BAD_REQUEST; - /* insure ap_escape_html will terminate correctly */ - field[len - 1] = '\0'; - apr_table_setn(r->notes, "error-notes", - apr_pstrcat(r->pool, - "Size of a request header field " - "exceeds server limit.<br />\n" - "<pre>\n", - ap_escape_html(r->pool, field), - "</pre>\n", NULL)); - return; - } - - if (rv != APR_SUCCESS) { - r->status = HTTP_BAD_REQUEST; - return; - } - - if (last_field != NULL) { - if ((len > 0) && ((*field == '\t') || *field == ' ')) { - /* This line is a continuation of the preceding line(s), - * so append it to the line that we've set aside. - * Note: this uses a power-of-two allocator to avoid - * doing O(n) allocs and using O(n^2) space for - * continuations that span many many lines. - */ - apr_size_t fold_len = last_len + len + 1; /* trailing null */ - - if ((fold_len - 1) > r->server->limit_req_fieldsize) { - r->status = HTTP_BAD_REQUEST; - /* report what we have accumulated so far before the - * overflow (last_field) as the field with the problem - */ - apr_table_setn(r->notes, "error-notes", - apr_pstrcat(r->pool, - "Size of a request header field " - "after folding " - "exceeds server limit.<br />\n" - "<pre>\n", - ap_escape_html(r->pool, last_field), - "</pre>\n", NULL)); - return; - } - - if (fold_len > alloc_len) { - char *fold_buf; - alloc_len += alloc_len; - if (fold_len > alloc_len) { - alloc_len = fold_len; - } - fold_buf = (char *)apr_palloc(r->pool, alloc_len); - memcpy(fold_buf, last_field, last_len); - last_field = fold_buf; - } - memcpy(last_field + last_len, field, len +1); /* +1 for nul */ - last_len += len; - folded = 1; - } - else /* not a continuation line */ { - - if (r->server->limit_req_fields - && (++fields_read > r->server->limit_req_fields)) { - r->status = HTTP_BAD_REQUEST; - apr_table_setn(r->notes, "error-notes", - "The number of request header fields " - "exceeds this server's limit."); - return; - } - - if (!(value = strchr(last_field, ':'))) { /* Find ':' or */ - r->status = HTTP_BAD_REQUEST; /* abort bad request */ - apr_table_setn(r->notes, "error-notes", - apr_pstrcat(r->pool, - "Request header field is " - "missing ':' separator.<br />\n" - "<pre>\n", - ap_escape_html(r->pool, - last_field), - "</pre>\n", NULL)); - return; - } - - tmp_field = value - 1; /* last character of field-name */ - - *value++ = '\0'; /* NUL-terminate at colon */ - - while (*value == ' ' || *value == '\t') { - ++value; /* Skip to start of value */ - } - - /* Strip LWS after field-name: */ - while (tmp_field > last_field - && (*tmp_field == ' ' || *tmp_field == '\t')) { - *tmp_field-- = '\0'; - } - - /* Strip LWS after field-value: */ - tmp_field = last_field + last_len - 1; - while (tmp_field > value - && (*tmp_field == ' ' || *tmp_field == '\t')) { - *tmp_field-- = '\0'; - } - - apr_table_addn(r->headers_in, last_field, value); - - /* reset the alloc_len so that we'll allocate a new - * buffer if we have to do any more folding: we can't - * use the previous buffer because its contents are - * now part of r->headers_in - */ - alloc_len = 0; - - } /* end if current line is not a continuation starting with tab */ - } - - /* Found a blank line, stop. */ - if (len == 0) { - break; - } - - /* Keep track of this line so that we can parse it on - * the next loop iteration. (In the folded case, last_field - * has been updated already.) - */ - if (!folded) { - last_field = field; - last_len = len; - } - } - - apr_table_compress(r->headers_in, APR_OVERLAP_TABLES_MERGE); -} - -AP_DECLARE(void) ap_get_mime_headers(request_rec *r) -{ - apr_bucket_brigade *tmp_bb; - tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - ap_get_mime_headers_core(r, tmp_bb); - apr_brigade_destroy(tmp_bb); -} - -request_rec *ap_read_request(conn_rec *conn) -{ - request_rec *r; - apr_pool_t *p; - const char *expect; - int access_status; - apr_bucket_brigade *tmp_bb; - - apr_pool_create(&p, conn->pool); - apr_pool_tag(p, "request"); - r = apr_pcalloc(p, sizeof(request_rec)); - r->pool = p; - r->connection = conn; - r->server = conn->base_server; - - r->user = NULL; - r->ap_auth_type = NULL; - - r->allowed_methods = ap_make_method_list(p, 2); - - r->headers_in = apr_table_make(r->pool, 25); - r->subprocess_env = apr_table_make(r->pool, 25); - r->headers_out = apr_table_make(r->pool, 12); - r->err_headers_out = apr_table_make(r->pool, 5); - r->notes = apr_table_make(r->pool, 5); - - r->request_config = ap_create_request_config(r->pool); - /* Must be set before we run create request hook */ - - r->proto_output_filters = conn->output_filters; - r->output_filters = r->proto_output_filters; - r->proto_input_filters = conn->input_filters; - r->input_filters = r->proto_input_filters; - ap_run_create_request(r); - r->per_dir_config = r->server->lookup_defaults; - - r->sent_bodyct = 0; /* bytect isn't for body */ - - r->read_length = 0; - r->read_body = REQUEST_NO_BODY; - - r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */ - r->the_request = NULL; - - tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - - /* Get the request... */ - if (!read_request_line(r, tmp_bb)) { - if (r->status == HTTP_REQUEST_URI_TOO_LARGE) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "request failed: URI too long (longer than %d)", r->server->limit_req_line); - ap_send_error_response(r, 0); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); - apr_brigade_destroy(tmp_bb); - return r; - } - - apr_brigade_destroy(tmp_bb); - return NULL; - } - - if (!r->assbackwards) { - ap_get_mime_headers_core(r, tmp_bb); - if (r->status != HTTP_REQUEST_TIME_OUT) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "request failed: error reading the headers"); - ap_send_error_response(r, 0); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); - apr_brigade_destroy(tmp_bb); - return r; - } - - if (apr_table_get(r->headers_in, "Transfer-Encoding") - && apr_table_get(r->headers_in, "Content-Length")) { - /* 2616 section 4.4, point 3: "if both Transfer-Encoding - * and Content-Length are received, the latter MUST be - * ignored"; so unset it here to prevent any confusion - * later. */ - apr_table_unset(r->headers_in, "Content-Length"); - } - } - else { - if (r->header_only) { - /* - * Client asked for headers only with HTTP/0.9, which doesn't send - * headers! Have to dink things just to make sure the error message - * comes through... - */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "client sent invalid HTTP/0.9 request: HEAD %s", - r->uri); - r->header_only = 0; - r->status = HTTP_BAD_REQUEST; - ap_send_error_response(r, 0); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); - apr_brigade_destroy(tmp_bb); - return r; - } - } - - apr_brigade_destroy(tmp_bb); - - r->status = HTTP_OK; /* Until further notice. */ - - /* update what we think the virtual host is based on the headers we've - * now read. may update status. - */ - ap_update_vhost_from_headers(r); - - /* we may have switched to another server */ - r->per_dir_config = r->server->lookup_defaults; - - if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1, 1))) - || ((r->proto_num == HTTP_VERSION(1, 1)) - && !apr_table_get(r->headers_in, "Host"))) { - /* - * Client sent us an HTTP/1.1 or later request without telling us the - * hostname, either with a full URL or a Host: header. We therefore - * need to (as per the 1.1 spec) send an error. As a special case, - * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain - * a Host: header, and the server MUST respond with 400 if it doesn't. - */ - r->status = HTTP_BAD_REQUEST; - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "client sent HTTP/1.1 request without hostname " - "(see RFC2616 section 14.23): %s", r->uri); - } - - if (r->status != HTTP_OK) { - ap_send_error_response(r, 0); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); - return r; - } - - if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL) - && (expect[0] != '\0')) { - /* - * The Expect header field was added to HTTP/1.1 after RFC 2068 - * as a means to signal when a 100 response is desired and, - * unfortunately, to signal a poor man's mandatory extension that - * the server must understand or return 417 Expectation Failed. - */ - if (strcasecmp(expect, "100-continue") == 0) { - r->expecting_100 = 1; - } - else { - r->status = HTTP_EXPECTATION_FAILED; - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "client sent an unrecognized expectation value of " - "Expect: %s", expect); - ap_send_error_response(r, 0); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); - return r; - } - } - - ap_add_input_filter_handle(ap_http_input_filter_handle, - NULL, r, r->connection); - - if ((access_status = ap_run_post_read_request(r))) { - ap_die(access_status, r); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); - return NULL; - } - - return r; -} - -/* - * A couple of other functions which initialize some of the fields of - * a request structure, as appropriate for adjuncts of one kind or another - * to a request in progress. Best here, rather than elsewhere, since - * *someone* has to set the protocol-specific fields... - */ - -AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, - const request_rec *r) -{ - rnew->the_request = r->the_request; /* Keep original request-line */ - - rnew->assbackwards = 1; /* Don't send headers from this. */ - rnew->no_local_copy = 1; /* Don't try to send HTTP_NOT_MODIFIED for a - * fragment. */ - rnew->method = "GET"; - rnew->method_number = M_GET; - rnew->protocol = "INCLUDED"; - - rnew->status = HTTP_OK; - - rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); - rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); - rnew->headers_out = apr_table_make(rnew->pool, 5); - rnew->err_headers_out = apr_table_make(rnew->pool, 5); - rnew->notes = apr_table_make(rnew->pool, 5); - - rnew->expecting_100 = r->expecting_100; - rnew->read_length = r->read_length; - rnew->read_body = REQUEST_NO_BODY; - - rnew->main = (request_rec *) r; -} - -static void end_output_stream(request_rec *r) -{ - conn_rec *c = r->connection; - apr_bucket_brigade *bb; - apr_bucket *b; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - ap_pass_brigade(r->output_filters, bb); -} - -AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) -{ - /* tell the filter chain there is no more content coming */ - if (!sub->eos_sent) { - end_output_stream(sub); - } -} - -/* finalize_request_protocol is called at completion of sending the - * response. Its sole purpose is to send the terminating protocol - * information for any wrappers around the response message body - * (i.e., transfer encodings). It should have been named finalize_response. - */ -AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r) -{ - (void) ap_discard_request_body(r); - - /* tell the filter chain there is no more content coming */ - if (!r->eos_sent) { - end_output_stream(r); - } -} - -/* - * Support for the Basic authentication protocol, and a bit for Digest. - */ -AP_DECLARE(void) ap_note_auth_failure(request_rec *r) -{ - const char *type = ap_auth_type(r); - if (type) { - if (!strcasecmp(type, "Basic")) - ap_note_basic_auth_failure(r); - else if (!strcasecmp(type, "Digest")) - ap_note_digest_auth_failure(r); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, - 0, r, "need AuthType to note auth failure: %s", r->uri); - } -} - -AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r) -{ - const char *type = ap_auth_type(r); - - /* if there is no AuthType configure or it is something other than - * Basic, let ap_note_auth_failure() deal with it - */ - if (!type || strcasecmp(type, "Basic")) - ap_note_auth_failure(r); - else - apr_table_setn(r->err_headers_out, - (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" - : "WWW-Authenticate", - apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), - "\"", NULL)); -} - -AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r) -{ - apr_table_setn(r->err_headers_out, - (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" - : "WWW-Authenticate", - /* need APR_TIME_T_FMT_HEX */ - apr_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%llx\"", - ap_auth_name(r), r->request_time)); -} - -AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) -{ - const char *auth_line = apr_table_get(r->headers_in, - (PROXYREQ_PROXY == r->proxyreq) - ? "Proxy-Authorization" - : "Authorization"); - const char *t; - - if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic")) - return DECLINED; - - if (!ap_auth_name(r)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, - 0, r, "need AuthName: %s", r->uri); - return HTTP_INTERNAL_SERVER_ERROR; - } - - if (!auth_line) { - ap_note_basic_auth_failure(r); - return HTTP_UNAUTHORIZED; - } - - if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) { - /* Client tried to authenticate using wrong auth scheme */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "client used wrong authentication scheme: %s", r->uri); - ap_note_basic_auth_failure(r); - return HTTP_UNAUTHORIZED; - } - - while (*auth_line == ' ' || *auth_line == '\t') { - auth_line++; - } - - t = ap_pbase64decode(r->pool, auth_line); - r->user = ap_getword_nulls (r->pool, &t, ':'); - r->ap_auth_type = "Basic"; - - *pw = t; - - return OK; -} - -struct content_length_ctx { - int data_sent; /* true if the C-L filter has already sent at - * least one bucket on to the next output filter - * for this request - */ -}; - -/* This filter computes the content length, but it also computes the number - * of bytes sent to the client. This means that this filter will always run - * through all of the buckets in all brigades - */ -AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter( - ap_filter_t *f, - apr_bucket_brigade *b) -{ - request_rec *r = f->r; - struct content_length_ctx *ctx; - apr_bucket *e; - int eos = 0; - apr_read_type_e eblock = APR_NONBLOCK_READ; - - ctx = f->ctx; - if (!ctx) { - f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx)); - ctx->data_sent = 0; - } - - /* Loop through this set of buckets to compute their length - */ - e = APR_BRIGADE_FIRST(b); - while (e != APR_BRIGADE_SENTINEL(b)) { - if (APR_BUCKET_IS_EOS(e)) { - eos = 1; - break; - } - if (e->length == (apr_size_t)-1) { - apr_size_t len; - const char *ignored; - apr_status_t rv; - - /* This is probably a pipe bucket. Send everything - * prior to this, and then read the data for this bucket. - */ - rv = apr_bucket_read(e, &ignored, &len, eblock); - if (rv == APR_SUCCESS) { - /* Attempt a nonblocking read next time through */ - eblock = APR_NONBLOCK_READ; - r->bytes_sent += len; - } - else if (APR_STATUS_IS_EAGAIN(rv)) { - /* Output everything prior to this bucket, and then - * do a blocking read on the next batch. - */ - if (e != APR_BRIGADE_FIRST(b)) { - apr_bucket_brigade *split = apr_brigade_split(b, e); - apr_bucket *flush = apr_bucket_flush_create(r->connection->bucket_alloc); - - APR_BRIGADE_INSERT_TAIL(b, flush); - rv = ap_pass_brigade(f->next, b); - if (rv != APR_SUCCESS || f->c->aborted) { - apr_brigade_destroy(split); - return rv; - } - b = split; - e = APR_BRIGADE_FIRST(b); - - ctx->data_sent = 1; - } - eblock = APR_BLOCK_READ; - continue; - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "ap_content_length_filter: " - "apr_bucket_read() failed"); - return rv; - } - } - else { - r->bytes_sent += e->length; - } - e = APR_BUCKET_NEXT(e); - } - - /* If we've now seen the entire response and it's otherwise - * okay to set the C-L in the response header, then do so now. - * - * We can only set a C-L in the response header if we haven't already - * sent any buckets on to the next output filter for this request. - */ - if (ctx->data_sent == 0 && eos && - /* don't whack the C-L if it has already been set for a HEAD - * by something like proxy. the brigade only has an EOS bucket - * in this case, making r->bytes_sent zero. - * - * if r->bytes_sent > 0 we have a (temporary) body whose length may - * have been changed by a filter. the C-L header might not have been - * updated so we do it here. long term it would be cleaner to have - * such filters update or remove the C-L header, and just use it - * if present. - */ - !(r->header_only && r->bytes_sent == 0 && - apr_table_get(r->headers_out, "Content-Length"))) { - ap_set_content_length(r, r->bytes_sent); - } - - ctx->data_sent = 1; - return ap_pass_brigade(f->next, b); -} - -/* - * Send the body of a response to the client. - */ -AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r, - apr_off_t offset, apr_size_t len, - apr_size_t *nbytes) -{ - conn_rec *c = r->connection; - apr_bucket_brigade *bb = NULL; - apr_bucket *b; - apr_status_t rv; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_file_create(fd, offset, len, r->pool, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - - rv = ap_pass_brigade(r->output_filters, bb); - if (rv != APR_SUCCESS) { - *nbytes = 0; /* no way to tell how many were actually sent */ - } - else { - *nbytes = len; - } - - return rv; -} - -#if APR_HAS_MMAP -/* send data from an in-memory buffer */ -AP_DECLARE(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset, - size_t length) -{ - conn_rec *c = r->connection; - apr_bucket_brigade *bb = NULL; - apr_bucket *b; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_mmap_create(mm, offset, length, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - ap_pass_brigade(r->output_filters, bb); - - return mm->size; /* XXX - change API to report apr_status_t? */ -} -#endif /* APR_HAS_MMAP */ - -typedef struct { - apr_bucket_brigade *bb; -} old_write_filter_ctx; - -AP_CORE_DECLARE_NONSTD(apr_status_t) ap_old_write_filter( - ap_filter_t *f, apr_bucket_brigade *bb) -{ - old_write_filter_ctx *ctx = f->ctx; - - AP_DEBUG_ASSERT(ctx); - - if (ctx->bb != 0) { - /* whatever is coming down the pipe (we don't care), we - * can simply insert our buffered data at the front and - * pass the whole bundle down the chain. - */ - APR_BRIGADE_CONCAT(ctx->bb, bb); - bb = ctx->bb; - ctx->bb = NULL; - } - - return ap_pass_brigade(f->next, bb); -} - -static apr_status_t buffer_output(request_rec *r, - const char *str, apr_size_t len) -{ - conn_rec *c = r->connection; - ap_filter_t *f; - old_write_filter_ctx *ctx; - - if (len == 0) - return APR_SUCCESS; - - /* future optimization: record some flags in the request_rec to - * say whether we've added our filter, and whether it is first. - */ - - /* this will typically exit on the first test */ - for (f = r->output_filters; f != NULL; f = f->next) { - if (ap_old_write_func == f->frec) - break; - } - - if (f == NULL) { - /* our filter hasn't been added yet */ - ctx = apr_pcalloc(r->pool, sizeof(*ctx)); - ap_add_output_filter("OLD_WRITE", ctx, r, r->connection); - f = r->output_filters; - } - - /* if the first filter is not our buffering filter, then we have to - * deliver the content through the normal filter chain - */ - if (f != r->output_filters) { - apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); - apr_bucket *b = apr_bucket_transient_create(str, len, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - - return ap_pass_brigade(r->output_filters, bb); - } - - /* grab the context from our filter */ - ctx = r->output_filters->ctx; - - if (ctx->bb == NULL) { - ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc); - } - - return ap_fwrite(f->next, ctx->bb, str, len); -} - -AP_DECLARE(int) ap_rputc(int c, request_rec *r) -{ - char c2 = (char)c; - - if (r->connection->aborted) { - return -1; - } - - if (buffer_output(r, &c2, 1) != APR_SUCCESS) - return -1; - - return c; -} - -AP_DECLARE(int) ap_rputs(const char *str, request_rec *r) -{ - apr_size_t len; - - if (r->connection->aborted) - return -1; - - if (buffer_output(r, str, len = strlen(str)) != APR_SUCCESS) - return -1; - - return len; -} - -AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) -{ - if (r->connection->aborted) - return -1; - - if (buffer_output(r, buf, nbyte) != APR_SUCCESS) - return -1; - - return nbyte; -} - -struct ap_vrprintf_data { - apr_vformatter_buff_t vbuff; - request_rec *r; - char *buff; -}; - -static apr_status_t r_flush(apr_vformatter_buff_t *buff) -{ - /* callback function passed to ap_vformatter to be called when - * vformatter needs to write into buff and buff.curpos > buff.endpos */ - - /* ap_vrprintf_data passed as a apr_vformatter_buff_t, which is then - * "downcast" to an ap_vrprintf_data */ - struct ap_vrprintf_data *vd = (struct ap_vrprintf_data*)buff; - - if (vd->r->connection->aborted) - return -1; - - /* r_flush is called when vbuff is completely full */ - if (buffer_output(vd->r, vd->buff, AP_IOBUFSIZE)) { - return -1; - } - - /* reset the buffer position */ - vd->vbuff.curpos = vd->buff; - vd->vbuff.endpos = vd->buff + AP_IOBUFSIZE; - - return APR_SUCCESS; -} - -AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va) -{ - apr_size_t written; - struct ap_vrprintf_data vd; - char vrprintf_buf[AP_IOBUFSIZE]; - - vd.vbuff.curpos = vrprintf_buf; - vd.vbuff.endpos = vrprintf_buf + AP_IOBUFSIZE; - vd.r = r; - vd.buff = vrprintf_buf; - - if (r->connection->aborted) - return -1; - - written = apr_vformatter(r_flush, &vd.vbuff, fmt, va); - - /* tack on null terminator on remaining string */ - *(vd.vbuff.curpos) = '\0'; - - if (written != -1) { - int n = vd.vbuff.curpos - vrprintf_buf; - - /* last call to buffer_output, to finish clearing the buffer */ - if (buffer_output(r, vrprintf_buf,n) != APR_SUCCESS) - return -1; - - written += n; - } - - return written; -} - -AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt, ...) -{ - va_list va; - int n; - - if (r->connection->aborted) - return -1; - - va_start(va, fmt); - n = ap_vrprintf(r, fmt, va); - va_end(va); - - return n; -} - -AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r, ...) -{ - va_list va; - const char *s; - apr_size_t len; - apr_size_t written = 0; - - if (r->connection->aborted) - return -1; - - /* ### TODO: if the total output is large, put all the strings - * ### into a single brigade, rather than flushing each time we - * ### fill the buffer - */ - va_start(va, r); - while (1) { - s = va_arg(va, const char *); - if (s == NULL) - break; - - len = strlen(s); - if (buffer_output(r, s, len) != APR_SUCCESS) { - return -1; - } - - written += len; - } - va_end(va); - - return written; -} - -AP_DECLARE(int) ap_rflush(request_rec *r) -{ - conn_rec *c = r->connection; - apr_bucket_brigade *bb; - apr_bucket *b; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) - return -1; - - return 0; -} - -/* - * This function sets the Last-Modified output header field to the value - * of the mtime field in the request structure - rationalized to keep it from - * being in the future. - */ -AP_DECLARE(void) ap_set_last_modified(request_rec *r) -{ - if (!r->assbackwards) { - apr_time_t mod_time = ap_rationalize_mtime(r, r->mtime); - char *datestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN); - - apr_rfc822_date(datestr, mod_time); - apr_table_setn(r->headers_out, "Last-Modified", datestr); - } -} - -AP_IMPLEMENT_HOOK_RUN_ALL(int,post_read_request, - (request_rec *r), (r), OK, DECLINED) -AP_IMPLEMENT_HOOK_RUN_ALL(int,log_transaction, - (request_rec *r), (r), OK, DECLINED) -AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,http_method, - (const request_rec *r), (r), NULL) -AP_IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port, - (const request_rec *r), (r), 0) diff --git a/rubbos/app/httpd-2.0.64/server/protocol.lo b/rubbos/app/httpd-2.0.64/server/protocol.lo deleted file mode 100644 index 21aa3dda..00000000 --- a/rubbos/app/httpd-2.0.64/server/protocol.lo +++ /dev/null @@ -1,12 +0,0 @@ -# protocol.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/protocol.o' - -# Name of the non-PIC object. -non_pic_object='protocol.o' - diff --git a/rubbos/app/httpd-2.0.64/server/protocol.o b/rubbos/app/httpd-2.0.64/server/protocol.o Binary files differdeleted file mode 100644 index dfe97714..00000000 --- a/rubbos/app/httpd-2.0.64/server/protocol.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/provider.c b/rubbos/app/httpd-2.0.64/server/provider.c deleted file mode 100644 index 10b5f88d..00000000 --- a/rubbos/app/httpd-2.0.64/server/provider.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_pools.h" -#include "apr_hash.h" - -#include "ap_provider.h" - -static apr_hash_t *global_providers = NULL; - -static apr_status_t cleanup_global_providers(void *ctx) -{ - global_providers = NULL; - return APR_SUCCESS; -} - -AP_DECLARE(apr_status_t) ap_register_provider(apr_pool_t *pool, - const char *provider_group, - const char *provider_name, - const char *provider_version, - const void *provider) -{ - apr_hash_t *provider_group_hash; - apr_hash_t *provider_version_hash; - - if (global_providers == NULL) { - global_providers = apr_hash_make(pool); - apr_pool_cleanup_register(pool, NULL, cleanup_global_providers, - apr_pool_cleanup_null); - } - - provider_group_hash = apr_hash_get(global_providers, provider_group, - APR_HASH_KEY_STRING); - - if (!provider_group_hash) { - provider_group_hash = apr_hash_make(pool); - apr_hash_set(global_providers, provider_group, APR_HASH_KEY_STRING, - provider_group_hash); - - } - - provider_version_hash = apr_hash_get(provider_group_hash, provider_name, - APR_HASH_KEY_STRING); - - if (!provider_version_hash) { - provider_version_hash = apr_hash_make(pool); - apr_hash_set(provider_group_hash, provider_name, APR_HASH_KEY_STRING, - provider_version_hash); - - } - - /* just set it. no biggy if it was there before. */ - apr_hash_set(provider_version_hash, provider_version, APR_HASH_KEY_STRING, - provider); - - return APR_SUCCESS; -} - -AP_DECLARE(void *) ap_lookup_provider(const char *provider_group, - const char *provider_name, - const char *provider_version) -{ - apr_hash_t *provider_group_hash, *provider_name_hash; - - if (global_providers == NULL) { - return NULL; - } - - provider_group_hash = apr_hash_get(global_providers, provider_group, - APR_HASH_KEY_STRING); - - if (provider_group_hash == NULL) { - return NULL; - } - - provider_name_hash = apr_hash_get(provider_group_hash, provider_name, - APR_HASH_KEY_STRING); - - if (provider_name_hash == NULL) { - return NULL; - } - - return apr_hash_get(provider_name_hash, provider_version, - APR_HASH_KEY_STRING); -} diff --git a/rubbos/app/httpd-2.0.64/server/provider.lo b/rubbos/app/httpd-2.0.64/server/provider.lo deleted file mode 100644 index ef717d2f..00000000 --- a/rubbos/app/httpd-2.0.64/server/provider.lo +++ /dev/null @@ -1,12 +0,0 @@ -# provider.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/provider.o' - -# Name of the non-PIC object. -non_pic_object='provider.o' - diff --git a/rubbos/app/httpd-2.0.64/server/provider.o b/rubbos/app/httpd-2.0.64/server/provider.o Binary files differdeleted file mode 100644 index 84297cfb..00000000 --- a/rubbos/app/httpd-2.0.64/server/provider.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/request.c b/rubbos/app/httpd-2.0.64/server/request.c deleted file mode 100644 index ef3a3042..00000000 --- a/rubbos/app/httpd-2.0.64/server/request.c +++ /dev/null @@ -1,1888 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * http_request.c: functions to get and process requests - * - * Rob McCool 3/21/93 - * - * Thoroughly revamped by rst for Apache. NB this file reads - * best from the bottom up. - * - */ - -#include "apr_strings.h" -#include "apr_file_io.h" -#include "apr_fnmatch.h" - -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_request.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_log.h" -#include "http_main.h" -#include "util_filter.h" -#include "util_charset.h" -#include "util_script.h" - -#include "mod_core.h" - -#if APR_HAVE_STDARG_H -#include <stdarg.h> -#endif - -APR_HOOK_STRUCT( - APR_HOOK_LINK(translate_name) - APR_HOOK_LINK(map_to_storage) - APR_HOOK_LINK(check_user_id) - APR_HOOK_LINK(fixups) - APR_HOOK_LINK(type_checker) - APR_HOOK_LINK(access_checker) - APR_HOOK_LINK(auth_checker) - APR_HOOK_LINK(insert_filter) - APR_HOOK_LINK(create_request) -) - -AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, - (request_rec *r), (r), DECLINED) -AP_IMPLEMENT_HOOK_RUN_FIRST(int,map_to_storage, - (request_rec *r), (r), DECLINED) -AP_IMPLEMENT_HOOK_RUN_FIRST(int,check_user_id, - (request_rec *r), (r), DECLINED) -AP_IMPLEMENT_HOOK_RUN_ALL(int,fixups, - (request_rec *r), (r), OK, DECLINED) -AP_IMPLEMENT_HOOK_RUN_FIRST(int,type_checker, - (request_rec *r), (r), DECLINED) -AP_IMPLEMENT_HOOK_RUN_ALL(int,access_checker, - (request_rec *r), (r), OK, DECLINED) -AP_IMPLEMENT_HOOK_RUN_FIRST(int,auth_checker, - (request_rec *r), (r), DECLINED) -AP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r)) -AP_IMPLEMENT_HOOK_RUN_ALL(int, create_request, - (request_rec *r), (r), OK, DECLINED) - - -static int decl_die(int status, char *phase, request_rec *r) -{ - if (status == DECLINED) { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, - "configuration error: couldn't %s: %s", phase, r->uri); - return HTTP_INTERNAL_SERVER_ERROR; - } - else { - return status; - } -} - -/* This is the master logic for processing requests. Do NOT duplicate - * this logic elsewhere, or the security model will be broken by future - * API changes. Each phase must be individually optimized to pick up - * redundant/duplicate calls by subrequests, and redirects. - */ -AP_DECLARE(int) ap_process_request_internal(request_rec *r) -{ - int file_req = (r->main && r->filename); - int access_status; - - /* Ignore embedded %2F's in path for proxy requests */ - if (!r->proxyreq && r->parsed_uri.path) { - core_dir_config *d; - d = ap_get_module_config(r->per_dir_config, &core_module); - if (d->allow_encoded_slashes) { - access_status = ap_unescape_url_keep2f(r->parsed_uri.path); - } - else { - access_status = ap_unescape_url(r->parsed_uri.path); - } - if (access_status) { - if (access_status == HTTP_NOT_FOUND) { - if (! d->allow_encoded_slashes) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "found %%2f (encoded '/') in URI " - "(decoded='%s'), returning 404", - r->parsed_uri.path); - } - } - return access_status; - } - } - - ap_getparents(r->uri); /* OK --- shrinking transformations... */ - - /* All file subrequests are a huge pain... they cannot bubble through the - * next several steps. Only file subrequests are allowed an empty uri, - * otherwise let translate_name kill the request. - */ - if (!file_req) { - if ((access_status = ap_location_walk(r))) { - return access_status; - } - - if ((access_status = ap_run_translate_name(r))) { - return decl_die(access_status, "translate", r); - } - } - - /* Reset to the server default config prior to running map_to_storage - */ - r->per_dir_config = r->server->lookup_defaults; - - if ((access_status = ap_run_map_to_storage(r))) { - /* This request wasn't in storage (e.g. TRACE) */ - return access_status; - } - - /* Excluding file-specific requests with no 'true' URI... - */ - if (!file_req) { - /* Rerun the location walk, which overrides any map_to_storage config. - */ - if ((access_status = ap_location_walk(r))) { - return access_status; - } - } - - /* Only on the main request! */ - if (r->main == NULL) { - if ((access_status = ap_run_header_parser(r))) { - return access_status; - } - } - - /* Skip authn/authz if the parent or prior request passed the authn/authz, - * and that configuration didn't change (this requires optimized _walk() - * functions in map_to_storage that use the same merge results given - * identical input.) If the config changes, we must re-auth. - */ - if (r->main && (r->main->per_dir_config == r->per_dir_config)) { - r->user = r->main->user; - r->ap_auth_type = r->main->ap_auth_type; - } - else if (r->prev && (r->prev->per_dir_config == r->per_dir_config)) { - r->user = r->prev->user; - r->ap_auth_type = r->prev->ap_auth_type; - } - else { - switch (ap_satisfies(r)) { - case SATISFY_ALL: - case SATISFY_NOSPEC: - if ((access_status = ap_run_access_checker(r)) != 0) { - return decl_die(access_status, "check access", r); - } - - if (ap_some_auth_required(r)) { - if (((access_status = ap_run_check_user_id(r)) != 0) - || !ap_auth_type(r)) { - return decl_die(access_status, ap_auth_type(r) - ? "check user. No user file?" - : "perform authentication. AuthType not set!", - r); - } - - if (((access_status = ap_run_auth_checker(r)) != 0) - || !ap_auth_type(r)) { - return decl_die(access_status, ap_auth_type(r) - ? "check access. No groups file?" - : "perform authentication. AuthType not set!", - r); - } - } - break; - - case SATISFY_ANY: - if (((access_status = ap_run_access_checker(r)) != 0)) { - if (!ap_some_auth_required(r)) { - return decl_die(access_status, "check access", r); - } - - if (((access_status = ap_run_check_user_id(r)) != 0) - || !ap_auth_type(r)) { - return decl_die(access_status, ap_auth_type(r) - ? "check user. No user file?" - : "perform authentication. AuthType not set!", - r); - } - - if (((access_status = ap_run_auth_checker(r)) != 0) - || !ap_auth_type(r)) { - return decl_die(access_status, ap_auth_type(r) - ? "check access. No groups file?" - : "perform authentication. AuthType not set!", - r); - } - } - break; - } - } - /* XXX Must make certain the ap_run_type_checker short circuits mime - * in mod-proxy for r->proxyreq && r->parsed_uri.scheme - * && !strcmp(r->parsed_uri.scheme, "http") - */ - if ((access_status = ap_run_type_checker(r)) != 0) { - return decl_die(access_status, "find types", r); - } - - if ((access_status = ap_run_fixups(r)) != 0) { - return access_status; - } - - return OK; -} - - -/* Useful caching structures to repeat _walk/merge sequences as required - * when a subrequest or redirect reuses substantially the same config. - * - * Directive order in the httpd.conf file and its Includes significantly - * impact this optimization. Grouping common blocks at the front of the - * config that are less likely to change between a request and - * its subrequests, or between a request and its redirects reduced - * the work of these functions significantly. - */ - -typedef struct walk_walked_t { - ap_conf_vector_t *matched; /* A dir_conf sections we matched */ - ap_conf_vector_t *merged; /* The dir_conf merged result */ -} walk_walked_t; - -typedef struct walk_cache_t { - const char *cached; /* The identifier we matched */ - ap_conf_vector_t **dir_conf_tested; /* The sections we matched against */ - ap_conf_vector_t *dir_conf_merged; /* Base per_dir_config */ - ap_conf_vector_t *per_dir_result; /* per_dir_config += walked result */ - apr_array_header_t *walked; /* The list of walk_walked_t results */ -} walk_cache_t; - -static walk_cache_t *prep_walk_cache(apr_size_t t, request_rec *r) -{ - walk_cache_t *cache; - void **note; - - /* Find the most relevant, recent entry to work from. That would be - * this request (on the second call), or the parent request of a - * subrequest, or the prior request of an internal redirect. Provide - * this _walk()er with a copy it is allowed to munge. If there is no - * parent or prior cached request, then create a new walk cache. - */ - note = ap_get_request_note(r, t); - if (!note) { - return NULL; - } - - if (!(cache = *note)) { - void **inherit_note; - - if ((r->main - && ((inherit_note = ap_get_request_note(r->main, t))) - && *inherit_note) - || (r->prev - && ((inherit_note = ap_get_request_note(r->prev, t))) - && *inherit_note)) { - cache = apr_pmemdup(r->pool, *inherit_note, - sizeof(*cache)); - cache->walked = apr_array_copy(r->pool, cache->walked); - } - else { - cache = apr_pcalloc(r->pool, sizeof(*cache)); - cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t)); - } - - *note = cache; - } - return cache; -} - -/***************************************************************** - * - * Getting and checking directory configuration. Also checks the - * FollowSymlinks and FollowSymOwner stuff, since this is really the - * only place that can happen (barring a new mid_dir_walk callout). - * - * We can't do it as an access_checker module function which gets - * called with the final per_dir_config, since we could have a directory - * with FollowSymLinks disabled, which contains a symlink to another - * with a .htaccess file which turns FollowSymLinks back on --- and - * access in such a case must be denied. So, whatever it is that - * checks FollowSymLinks needs to know the state of the options as - * they change, all the way down. - */ - - -/* - * resolve_symlink must _always_ be called on an APR_LNK file type! - * It will resolve the actual target file type, modification date, etc, - * and provide any processing required for symlink evaluation. - * Path must already be cleaned, no trailing slash, no multi-slashes, - * and don't call this on the root! - * - * Simply, the number of times we deref a symlink are minimal compared - * to the number of times we had an extra lstat() since we 'weren't sure'. - * - * To optimize, we stat() anything when given (opts & OPT_SYM_LINKS), otherwise - * we start off with an lstat(). Every lstat() must be dereferenced in case - * it points at a 'nasty' - we must always rerun check_safe_file (or similar.) - */ -static int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p) -{ - apr_finfo_t fi; - int res; - const char *savename; - - if (!(opts & (OPT_SYM_OWNER | OPT_SYM_LINKS))) { - return HTTP_FORBIDDEN; - } - - /* Save the name from the valid bits. */ - savename = (lfi->valid & APR_FINFO_NAME) ? lfi->name : NULL; - - if (opts & OPT_SYM_LINKS) { - if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME - | APR_FINFO_LINK), p)) - != APR_SUCCESS) { - return HTTP_FORBIDDEN; - } - - /* Give back the target */ - memcpy(lfi, &fi, sizeof(fi)); - if (savename) { - lfi->name = savename; - lfi->valid |= APR_FINFO_NAME; - } - - return OK; - } - - /* OPT_SYM_OWNER only works if we can get the owner of - * both the file and symlink. First fill in a missing - * owner of the symlink, then get the info of the target. - */ - if (!(lfi->valid & APR_FINFO_OWNER)) { - if ((res = apr_lstat(&fi, d, lfi->valid | APR_FINFO_OWNER, p)) - != APR_SUCCESS) { - return HTTP_FORBIDDEN; - } - } - - if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME), p)) - != APR_SUCCESS) { - return HTTP_FORBIDDEN; - } - - if (apr_compare_users(fi.user, lfi->user) != APR_SUCCESS) { - return HTTP_FORBIDDEN; - } - - /* Give back the target */ - memcpy(lfi, &fi, sizeof(fi)); - if (savename) { - lfi->name = savename; - lfi->valid |= APR_FINFO_NAME; - } - - return OK; -} - - -/* - * As we walk the directory configuration, the merged config won't - * be 'rooted' to a specific vhost until the very end of the merge. - * - * We need a very fast mini-merge to a real, vhost-rooted merge - * of core.opts and core.override, the only options tested within - * directory_walk itself. - * - * See core.c::merge_core_dir_configs() for explanation. - */ - -typedef struct core_opts_t { - allow_options_t opts; - allow_options_t add; - allow_options_t remove; - overrides_t override; -} core_opts_t; - -static void core_opts_merge(const ap_conf_vector_t *sec, core_opts_t *opts) -{ - core_dir_config *this_dir = ap_get_module_config(sec, &core_module); - - if (!this_dir) { - return; - } - - if (this_dir->opts & OPT_UNSET) { - opts->add = (opts->add & ~this_dir->opts_remove) - | this_dir->opts_add; - opts->remove = (opts->remove & ~this_dir->opts_add) - | this_dir->opts_remove; - opts->opts = (opts->opts & ~opts->remove) | opts->add; - } - else { - opts->opts = this_dir->opts; - opts->add = this_dir->opts_add; - opts->remove = this_dir->opts_remove; - } - - if (!(this_dir->override & OR_UNSET)) { - opts->override = this_dir->override; - } -} - - -/***************************************************************** - * - * Getting and checking directory configuration. Also checks the - * FollowSymlinks and FollowSymOwner stuff, since this is really the - * only place that can happen (barring a new mid_dir_walk callout). - * - * We can't do it as an access_checker module function which gets - * called with the final per_dir_config, since we could have a directory - * with FollowSymLinks disabled, which contains a symlink to another - * with a .htaccess file which turns FollowSymLinks back on --- and - * access in such a case must be denied. So, whatever it is that - * checks FollowSymLinks needs to know the state of the options as - * they change, all the way down. - */ - -AP_DECLARE(int) ap_directory_walk(request_rec *r) -{ - ap_conf_vector_t *now_merged = NULL; - core_server_config *sconf = ap_get_module_config(r->server->module_config, - &core_module); - ap_conf_vector_t **sec_ent = (ap_conf_vector_t **) sconf->sec_dir->elts; - int num_sec = sconf->sec_dir->nelts; - walk_cache_t *cache; - char *entry_dir; - apr_status_t rv; - - /* XXX: Better (faster) tests needed!!! - * - * "OK" as a response to a real problem is not _OK_, but to allow broken - * modules to proceed, we will permit the not-a-path filename to pass the - * following two tests. This behavior may be revoked in future versions - * of Apache. We still must catch it later if it's heading for the core - * handler. Leave INFO notes here for module debugging. - */ - if (r->filename == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "Module bug? Request filename is missing for URI %s", - r->uri); - return OK; - } - - /* Canonicalize the file path without resolving filename case or aliases - * so we can begin by checking the cache for a recent directory walk. - * This call will ensure we have an absolute path in the same pass. - */ - if ((rv = apr_filepath_merge(&entry_dir, NULL, r->filename, - APR_FILEPATH_NOTRELATIVE, r->pool)) - != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "Module bug? Request filename path %s is invalid or " - "or not absolute for uri %s", - r->filename, r->uri); - return OK; - } - - /* XXX Notice that this forces path_info to be canonical. That might - * not be desired by all apps. However, some of those same apps likely - * have significant security holes. - */ - r->filename = entry_dir; - - cache = prep_walk_cache(AP_NOTE_DIRECTORY_WALK, r); - - /* If this is not a dirent subrequest with a preconstructed - * r->finfo value, then we can simply stat the filename to - * save burning mega-cycles with unneeded stats - if this is - * an exact file match. We don't care about failure... we - * will stat by component failing this meager attempt. - * - * It would be nice to distinguish APR_ENOENT from other - * types of failure, such as APR_ENOTDIR. We can do something - * with APR_ENOENT, knowing that the path is good. - */ - if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) { - rv = apr_stat(&r->finfo, r->filename, APR_FINFO_MIN, r->pool); - - /* some OSs will return APR_SUCCESS/APR_REG if we stat - * a regular file but we have '/' at the end of the name; - * - * other OSs will return APR_ENOTDIR for that situation; - * - * handle it the same everywhere by simulating a failure - * if it looks like a directory but really isn't - * - * Also reset if the stat failed, just for safety. - */ - if ((rv != APR_SUCCESS) || - (r->finfo.filetype && - (r->finfo.filetype != APR_DIR) && - (r->filename[strlen(r->filename) - 1] == '/'))) { - r->finfo.filetype = 0; /* forget what we learned */ - } - } - - if (r->finfo.filetype == APR_REG) { - entry_dir = ap_make_dirstr_parent(r->pool, entry_dir); - } - else if (r->filename[strlen(r->filename) - 1] != '/') { - entry_dir = apr_pstrcat(r->pool, r->filename, "/", NULL); - } - - /* If we have a file already matches the path of r->filename, - * and the vhost's list of directory sections hasn't changed, - * we can skip rewalking the directory_walk entries. - */ - if (cache->cached - && ((r->finfo.filetype == APR_REG) - || ((r->finfo.filetype == APR_DIR) - && (!r->path_info || !*r->path_info))) - && (cache->dir_conf_tested == sec_ent) - && (strcmp(entry_dir, cache->cached) == 0)) { - /* Well this looks really familiar! If our end-result (per_dir_result) - * didn't change, we have absolutely nothing to do :) - * Otherwise (as is the case with most dir_merged/file_merged requests) - * we must merge our dir_conf_merged onto this new r->per_dir_config. - */ - if (r->per_dir_config == cache->per_dir_result) { - return OK; - } - - if (r->per_dir_config == cache->dir_conf_merged) { - r->per_dir_config = cache->per_dir_result; - return OK; - } - - if (cache->walked->nelts) { - now_merged = ((walk_walked_t*)cache->walked->elts) - [cache->walked->nelts - 1].merged; - } - } - else { - /* We start now_merged from NULL since we want to build - * a locations list that can be merged to any vhost. - */ - int sec_idx; - int matches = cache->walked->nelts; - walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; - core_dir_config *this_dir; - core_opts_t opts; - apr_finfo_t thisinfo; - char *save_path_info; - apr_size_t buflen; - char *buf; - unsigned int seg, startseg; - - /* Invariant: from the first time filename_len is set until - * it goes out of scope, filename_len==strlen(r->filename) - */ - apr_size_t filename_len; -#ifdef CASE_BLIND_FILESYSTEM - apr_size_t canonical_len; -#endif - - /* - * We must play our own mini-merge game here, for the few - * running dir_config values we care about within dir_walk. - * We didn't start the merge from r->per_dir_config, so we - * accumulate opts and override as we merge, from the globals. - */ - this_dir = ap_get_module_config(r->per_dir_config, &core_module); - opts.opts = this_dir->opts; - opts.add = this_dir->opts_add; - opts.remove = this_dir->opts_remove; - opts.override = this_dir->override; - - /* Set aside path_info to merge back onto path_info later. - * If r->filename is a directory, we must remerge the path_info, - * before we continue! [Directories cannot, by defintion, have - * path info. Either the next segment is not-found, or a file.] - * - * r->path_info tracks the unconsumed source path. - * r->filename tracks the path as we process it - */ - if ((r->finfo.filetype == APR_DIR) && r->path_info && *r->path_info) - { - if ((rv = apr_filepath_merge(&r->path_info, r->filename, - r->path_info, - APR_FILEPATH_NOTABOVEROOT, r->pool)) - != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "dir_walk error, path_info %s is not relative " - "to the filename path %s for uri %s", - r->path_info, r->filename, r->uri); - return HTTP_INTERNAL_SERVER_ERROR; - } - - save_path_info = NULL; - } - else { - save_path_info = r->path_info; - r->path_info = r->filename; - } - -#ifdef CASE_BLIND_FILESYSTEM - - canonical_len = 0; - while (r->canonical_filename && r->canonical_filename[canonical_len] - && (r->canonical_filename[canonical_len] - == r->path_info[canonical_len])) { - ++canonical_len; - } - - while (canonical_len - && ((r->canonical_filename[canonical_len - 1] != '/' - && r->canonical_filename[canonical_len - 1]) - || (r->path_info[canonical_len - 1] != '/' - && r->path_info[canonical_len - 1]))) { - --canonical_len; - } - - /* - * Now build r->filename component by component, starting - * with the root (on Unix, simply "/"). We will make a huge - * assumption here for efficiency, that any canonical path - * already given included a canonical root. - */ - rv = apr_filepath_root((const char **)&r->filename, - (const char **)&r->path_info, - canonical_len ? 0 : APR_FILEPATH_TRUENAME, - r->pool); - filename_len = strlen(r->filename); - - /* - * Bad assumption above? If the root's length is longer - * than the canonical length, then it cannot be trusted as - * a truename. So try again, this time more seriously. - */ - if ((rv == APR_SUCCESS) && canonical_len - && (filename_len > canonical_len)) { - rv = apr_filepath_root((const char **)&r->filename, - (const char **)&r->path_info, - APR_FILEPATH_TRUENAME, r->pool); - filename_len = strlen(r->filename); - canonical_len = 0; - } - -#else /* ndef CASE_BLIND_FILESYSTEM, really this simple for Unix today; */ - - rv = apr_filepath_root((const char **)&r->filename, - (const char **)&r->path_info, - 0, r->pool); - filename_len = strlen(r->filename); - -#endif - - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "dir_walk error, could not determine the root " - "path of filename %s%s for uri %s", - r->filename, r->path_info, r->uri); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* Working space for terminating null and an extra / is required. - */ - buflen = filename_len + strlen(r->path_info) + 2; - buf = apr_palloc(r->pool, buflen); - memcpy(buf, r->filename, filename_len + 1); - r->filename = buf; - thisinfo.valid = APR_FINFO_TYPE; - thisinfo.filetype = APR_DIR; /* It's the root, of course it's a dir */ - - /* - * seg keeps track of which segment we've copied. - * sec_idx keeps track of which section we're on, since sections are - * ordered by number of segments. See core_reorder_directories - * startseg tells us how many segments describe the root path - * e.g. the complete path "//host/foo/" to a UNC share (4) - */ - startseg = seg = ap_count_dirs(r->filename); - sec_idx = 0; - - /* - * Go down the directory hierarchy. Where we have to check for - * symlinks, do so. Where a .htaccess file has permission to - * override anything, try to find one. - */ - do { - int res; - char *seg_name; - char *delim; - int temp_slash=0; - - /* We have no trailing slash, but we sure would appreciate one. - * However, we don't want to append a / our first time through. - */ - if ((seg > startseg) && r->filename[filename_len-1] != '/') { - r->filename[filename_len++] = '/'; - r->filename[filename_len] = 0; - temp_slash=1; - } - - /* Begin *this* level by looking for matching <Directory> sections - * from the server config. - */ - for (; sec_idx < num_sec; ++sec_idx) { - - ap_conf_vector_t *entry_config = sec_ent[sec_idx]; - core_dir_config *entry_core; - entry_core = ap_get_module_config(entry_config, &core_module); - - /* No more possible matches for this many segments? - * We are done when we find relative/regex/longer components. - */ - if (entry_core->r || entry_core->d_components > seg) { - break; - } - - /* We will never skip '0' element components, e.g. plain old - * <Directory >, and <Directory "/"> are classified as zero - * so that Win32/Netware/OS2 etc all pick them up. - * Otherwise, skip over the mismatches. - */ - if (entry_core->d_components - && ((entry_core->d_components < seg) - || (entry_core->d_is_fnmatch - ? (apr_fnmatch(entry_core->d, r->filename, - FNM_PATHNAME) != APR_SUCCESS) - : (strcmp(r->filename, entry_core->d) != 0)))) { - continue; - } - - /* If we haven't continue'd above, we have a match. - * - * Calculate our full-context core opts & override. - */ - core_opts_merge(sec_ent[sec_idx], &opts); - - /* If we merged this same section last time, reuse it - */ - if (matches) { - if (last_walk->matched == sec_ent[sec_idx]) { - now_merged = last_walk->merged; - ++last_walk; - --matches; - continue; - } - - /* We fell out of sync. This is our own copy of walked, - * so truncate the remaining matches and reset remaining. - */ - cache->walked->nelts -= matches; - matches = 0; - } - - if (now_merged) { - now_merged = ap_merge_per_dir_configs(r->pool, - now_merged, - sec_ent[sec_idx]); - } - else { - now_merged = sec_ent[sec_idx]; - } - - last_walk = (walk_walked_t*)apr_array_push(cache->walked); - last_walk->matched = sec_ent[sec_idx]; - last_walk->merged = now_merged; - } - - /* If .htaccess files are enabled, check for one, provided we - * have reached a real path. - */ - do { /* Not really a loop, just a break'able code block */ - - ap_conf_vector_t *htaccess_conf = NULL; - - /* No htaccess in an incomplete root path, - * nor if it's disabled - */ - if (seg < startseg || !opts.override) { - break; - } - - res = ap_parse_htaccess(&htaccess_conf, r, opts.override, - apr_pstrdup(r->pool, r->filename), - sconf->access_name); - if (res) { - return res; - } - - if (!htaccess_conf) { - break; - } - - /* If we are still here, we found our htaccess. - * - * Calculate our full-context core opts & override. - */ - core_opts_merge(htaccess_conf, &opts); - - /* If we merged this same htaccess last time, reuse it... - * this wouldn't work except that we cache the htaccess - * sections for the lifetime of the request, so we match - * the same conf. Good planning (no, pure luck ;) - */ - if (matches) { - if (last_walk->matched == htaccess_conf) { - now_merged = last_walk->merged; - ++last_walk; - --matches; - break; - } - - /* We fell out of sync. This is our own copy of walked, - * so truncate the remaining matches and reset - * remaining. - */ - cache->walked->nelts -= matches; - matches = 0; - } - - if (now_merged) { - now_merged = ap_merge_per_dir_configs(r->pool, - now_merged, - htaccess_conf); - } - else { - now_merged = htaccess_conf; - } - - last_walk = (walk_walked_t*)apr_array_push(cache->walked); - last_walk->matched = htaccess_conf; - last_walk->merged = now_merged; - - } while (0); /* Only one htaccess, not a real loop */ - - /* That temporary trailing slash was useful, now drop it. - */ - if (temp_slash) { - r->filename[--filename_len] = '\0'; - } - - /* Time for all good things to come to an end? - */ - if (!r->path_info || !*r->path_info) { - break; - } - - /* Now it's time for the next segment... - * We will assume the next element is an end node, and fix it up - * below as necessary... - */ - - seg_name = r->filename + filename_len; - delim = strchr(r->path_info + (*r->path_info == '/' ? 1 : 0), '/'); - if (delim) { - size_t path_info_len = delim - r->path_info; - *delim = '\0'; - memcpy(seg_name, r->path_info, path_info_len + 1); - filename_len += path_info_len; - r->path_info = delim; - *delim = '/'; - } - else { - size_t path_info_len = strlen(r->path_info); - memcpy(seg_name, r->path_info, path_info_len + 1); - filename_len += path_info_len; - r->path_info += path_info_len; - } - if (*seg_name == '/') - ++seg_name; - - /* If nothing remained but a '/' string, we are finished - */ - if (!*seg_name) { - break; - } - - /* First optimization; - * If...we knew r->filename was a file, and - * if...we have strict (case-sensitive) filenames, or - * we know the canonical_filename matches to _this_ name, and - * if...we have allowed symlinks - * skip the lstat and dummy up an APR_DIR value for thisinfo. - */ - if (r->finfo.filetype -#ifdef CASE_BLIND_FILESYSTEM - && (filename_len <= canonical_len) -#endif - && ((opts.opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS)) - { - - thisinfo.filetype = APR_DIR; - ++seg; - continue; - } - - /* We choose apr_lstat here, rather that apr_stat, so that we - * capture this path object rather than its target. We will - * replace the info with our target's info below. We especially - * want the name of this 'link' object, not the name of its - * target, if we are fixing the filename case/resolving aliases. - */ - rv = apr_lstat(&thisinfo, r->filename, - APR_FINFO_MIN | APR_FINFO_NAME, r->pool); - - if (APR_STATUS_IS_ENOENT(rv)) { - /* Nothing? That could be nice. But our directory - * walk is done. - */ - thisinfo.filetype = APR_NOFILE; - break; - } - else if (APR_STATUS_IS_EACCES(rv)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "access to %s denied", r->uri); - return r->status = HTTP_FORBIDDEN; - } - else if ((rv != APR_SUCCESS && rv != APR_INCOMPLETE) - || !(thisinfo.valid & APR_FINFO_TYPE)) { - /* If we hit ENOTDIR, we must have over-optimized, deny - * rather than assume not found. - */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "access to %s failed", r->uri); - return r->status = HTTP_FORBIDDEN; - } - - /* Fix up the path now if we have a name, and they don't agree - */ - if ((thisinfo.valid & APR_FINFO_NAME) - && strcmp(seg_name, thisinfo.name)) { - /* TODO: provide users an option that an internal/external - * redirect is required here? We need to walk the URI and - * filename in tandem to properly correlate these. - */ - strcpy(seg_name, thisinfo.name); - filename_len = strlen(r->filename); - } - - if (thisinfo.filetype == APR_LNK) { - /* Is this a possibly acceptable symlink? - */ - if ((res = resolve_symlink(r->filename, &thisinfo, - opts.opts, r->pool)) != OK) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Symbolic link not allowed: %s", - r->filename); - return r->status = res; - } - } - - /* Ok, we are done with the link's info, test the real target - */ - if (thisinfo.filetype == APR_REG || - thisinfo.filetype == APR_NOFILE) { - /* That was fun, nothing left for us here - */ - break; - } - else if (thisinfo.filetype != APR_DIR) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Forbidden: %s doesn't point to " - "a file or directory", - r->filename); - return r->status = HTTP_FORBIDDEN; - } - - ++seg; - } while (thisinfo.filetype == APR_DIR); - - /* If we have _not_ optimized, this is the time to recover - * the final stat result. - */ - if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) { - r->finfo = thisinfo; - } - - /* Now splice the saved path_info back onto any new path_info - */ - if (save_path_info) { - if (r->path_info && *r->path_info) { - r->path_info = ap_make_full_path(r->pool, r->path_info, - save_path_info); - } - else { - r->path_info = save_path_info; - } - } - - /* - * Now we'll deal with the regexes, note we pick up sec_idx - * where we left off (we gave up after we hit entry_core->r) - */ - for (; sec_idx < num_sec; ++sec_idx) { - - core_dir_config *entry_core; - entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module); - - if (!entry_core->r) { - continue; - } - - if (ap_regexec(entry_core->r, r->filename, 0, NULL, REG_NOTEOL)) { - continue; - } - - /* If we haven't already continue'd above, we have a match. - * - * Calculate our full-context core opts & override. - */ - core_opts_merge(sec_ent[sec_idx], &opts); - - /* If we merged this same section last time, reuse it - */ - if (matches) { - if (last_walk->matched == sec_ent[sec_idx]) { - now_merged = last_walk->merged; - ++last_walk; - --matches; - continue; - } - - /* We fell out of sync. This is our own copy of walked, - * so truncate the remaining matches and reset remaining. - */ - cache->walked->nelts -= matches; - matches = 0; - } - - if (now_merged) { - now_merged = ap_merge_per_dir_configs(r->pool, - now_merged, - sec_ent[sec_idx]); - } - else { - now_merged = sec_ent[sec_idx]; - } - - last_walk = (walk_walked_t*)apr_array_push(cache->walked); - last_walk->matched = sec_ent[sec_idx]; - last_walk->merged = now_merged; - } - - /* Whoops - everything matched in sequence, but the original walk - * found some additional matches. Truncate them. - */ - if (matches) { - cache->walked->nelts -= matches; - } - } - -/* It seems this shouldn't be needed anymore. We translated the - x symlink above into a real resource, and should have died up there. - x Even if we keep this, it needs more thought (maybe an r->file_is_symlink) - x perhaps it should actually happen in file_walk, so we catch more - x obscure cases in autoindex subrequests, etc. - x - x * Symlink permissions are determined by the parent. If the request is - x * for a directory then applying the symlink test here would use the - x * permissions of the directory as opposed to its parent. Consider a - x * symlink pointing to a dir with a .htaccess disallowing symlinks. If - x * you access /symlink (or /symlink/) you would get a 403 without this - x * APR_DIR test. But if you accessed /symlink/index.html, for example, - x * you would *not* get the 403. - x - x if (r->finfo.filetype != APR_DIR - x && (res = resolve_symlink(r->filename, r->info, ap_allow_options(r), - x r->pool))) { - x ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - x "Symbolic link not allowed: %s", r->filename); - x return res; - x } - */ - - /* Save future sub-requestors much angst in processing - * this subrequest. If dir_walk couldn't canonicalize - * the file path, nothing can. - */ - r->canonical_filename = r->filename; - - if (r->finfo.filetype == APR_DIR) { - cache->cached = r->filename; - } - else { - cache->cached = ap_make_dirstr_parent(r->pool, r->filename); - } - - cache->dir_conf_tested = sec_ent; - cache->dir_conf_merged = r->per_dir_config; - - /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs, - * and note the end result to (potentially) skip this step next time. - */ - if (now_merged) { - r->per_dir_config = ap_merge_per_dir_configs(r->pool, - r->per_dir_config, - now_merged); - } - cache->per_dir_result = r->per_dir_config; - - return OK; -} - - -AP_DECLARE(int) ap_location_walk(request_rec *r) -{ - ap_conf_vector_t *now_merged = NULL; - core_server_config *sconf = ap_get_module_config(r->server->module_config, - &core_module); - ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)sconf->sec_url->elts; - int num_sec = sconf->sec_url->nelts; - walk_cache_t *cache; - const char *entry_uri; - - /* No tricks here, there are no <Locations > to parse in this vhost. - * We won't destroy the cache, just in case _this_ redirect is later - * redirected again to a vhost with <Location > blocks to optimize. - */ - if (!num_sec) { - return OK; - } - - cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); - - /* Location and LocationMatch differ on their behaviour w.r.t. multiple - * slashes. Location matches multiple slashes with a single slash, - * LocationMatch doesn't. An exception, for backwards brokenness is - * absoluteURIs... in which case neither match multiple slashes. - */ - if (r->uri[0] != '/') { - entry_uri = r->uri; - } - else { - char *uri = apr_pstrdup(r->pool, r->uri); - ap_no2slash(uri); - entry_uri = uri; - } - - /* If we have an cache->cached location that matches r->uri, - * and the vhost's list of locations hasn't changed, we can skip - * rewalking the location_walk entries. - */ - if (cache->cached - && (cache->dir_conf_tested == sec_ent) - && (strcmp(entry_uri, cache->cached) == 0)) { - /* Well this looks really familiar! If our end-result (per_dir_result) - * didn't change, we have absolutely nothing to do :) - * Otherwise (as is the case with most dir_merged/file_merged requests) - * we must merge our dir_conf_merged onto this new r->per_dir_config. - */ - if (r->per_dir_config == cache->per_dir_result) { - return OK; - } - - if (r->per_dir_config == cache->dir_conf_merged) { - r->per_dir_config = cache->per_dir_result; - return OK; - } - - if (cache->walked->nelts) { - now_merged = ((walk_walked_t*)cache->walked->elts) - [cache->walked->nelts - 1].merged; - } - } - else { - /* We start now_merged from NULL since we want to build - * a locations list that can be merged to any vhost. - */ - int len, sec_idx; - int matches = cache->walked->nelts; - walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; - cache->cached = entry_uri; - - /* Go through the location entries, and check for matches. - * We apply the directive sections in given order, we should - * really try them with the most general first. - */ - for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) { - - core_dir_config *entry_core; - entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module); - - /* ### const strlen can be optimized in location config parsing */ - len = strlen(entry_core->d); - - /* Test the regex, fnmatch or string as appropriate. - * If it's a strcmp, and the <Location > pattern was - * not slash terminated, then this uri must be slash - * terminated (or at the end of the string) to match. - */ - if (entry_core->r - ? ap_regexec(entry_core->r, r->uri, 0, NULL, 0) - : (entry_core->d_is_fnmatch - ? apr_fnmatch(entry_core->d, cache->cached, FNM_PATHNAME) - : (strncmp(entry_core->d, cache->cached, len) - || (entry_core->d[len - 1] != '/' - && cache->cached[len] != '/' - && cache->cached[len] != '\0')))) { - continue; - } - - /* If we merged this same section last time, reuse it - */ - if (matches) { - if (last_walk->matched == sec_ent[sec_idx]) { - now_merged = last_walk->merged; - ++last_walk; - --matches; - continue; - } - - /* We fell out of sync. This is our own copy of walked, - * so truncate the remaining matches and reset remaining. - */ - cache->walked->nelts -= matches; - matches = 0; - } - - if (now_merged) { - now_merged = ap_merge_per_dir_configs(r->pool, - now_merged, - sec_ent[sec_idx]); - } - else { - now_merged = sec_ent[sec_idx]; - } - - last_walk = (walk_walked_t*)apr_array_push(cache->walked); - last_walk->matched = sec_ent[sec_idx]; - last_walk->merged = now_merged; - } - - /* Whoops - everything matched in sequence, but the original walk - * found some additional matches. Truncate them. - */ - if (matches) { - cache->walked->nelts -= matches; - } - } - - cache->dir_conf_tested = sec_ent; - cache->dir_conf_merged = r->per_dir_config; - - /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs, - * and note the end result to (potentially) skip this step next time. - */ - if (now_merged) { - r->per_dir_config = ap_merge_per_dir_configs(r->pool, - r->per_dir_config, - now_merged); - } - cache->per_dir_result = r->per_dir_config; - - return OK; -} - -AP_DECLARE(int) ap_file_walk(request_rec *r) -{ - ap_conf_vector_t *now_merged = NULL; - core_dir_config *dconf = ap_get_module_config(r->per_dir_config, - &core_module); - ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)dconf->sec_file->elts; - int num_sec = dconf->sec_file->nelts; - walk_cache_t *cache; - const char *test_file; - - /* To allow broken modules to proceed, we allow missing filenames to pass. - * We will catch it later if it's heading for the core handler. - * directory_walk already posted an INFO note for module debugging. - */ - if (r->filename == NULL) { - return OK; - } - - cache = prep_walk_cache(AP_NOTE_FILE_WALK, r); - - /* No tricks here, there are just no <Files > to parse in this context. - * We won't destroy the cache, just in case _this_ redirect is later - * redirected again to a context containing the same or similar <Files >. - */ - if (!num_sec) { - return OK; - } - - /* Get the basename .. and copy for the cache just - * in case r->filename is munged by another module - */ - test_file = strrchr(r->filename, '/'); - if (test_file == NULL) { - test_file = apr_pstrdup(r->pool, r->filename); - } - else { - test_file = apr_pstrdup(r->pool, ++test_file); - } - - /* If we have an cache->cached file name that matches test_file, - * and the directory's list of file sections hasn't changed, we - * can skip rewalking the file_walk entries. - */ - if (cache->cached - && (cache->dir_conf_tested == sec_ent) - && (strcmp(test_file, cache->cached) == 0)) { - /* Well this looks really familiar! If our end-result (per_dir_result) - * didn't change, we have absolutely nothing to do :) - * Otherwise (as is the case with most dir_merged requests) - * we must merge our dir_conf_merged onto this new r->per_dir_config. - */ - if (r->per_dir_config == cache->per_dir_result) { - return OK; - } - - if (r->per_dir_config == cache->dir_conf_merged) { - r->per_dir_config = cache->per_dir_result; - return OK; - } - - if (cache->walked->nelts) { - now_merged = ((walk_walked_t*)cache->walked->elts) - [cache->walked->nelts - 1].merged; - } - } - else { - /* We start now_merged from NULL since we want to build - * a file section list that can be merged to any dir_walk. - */ - int sec_idx; - int matches = cache->walked->nelts; - walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; - cache->cached = test_file; - - /* Go through the location entries, and check for matches. - * We apply the directive sections in given order, we should - * really try them with the most general first. - */ - for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) { - - core_dir_config *entry_core; - entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module); - - if (entry_core->r - ? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0) - : (entry_core->d_is_fnmatch - ? apr_fnmatch(entry_core->d, cache->cached, FNM_PATHNAME) - : strcmp(entry_core->d, cache->cached))) { - continue; - } - - /* If we merged this same section last time, reuse it - */ - if (matches) { - if (last_walk->matched == sec_ent[sec_idx]) { - now_merged = last_walk->merged; - ++last_walk; - --matches; - continue; - } - - /* We fell out of sync. This is our own copy of walked, - * so truncate the remaining matches and reset remaining. - */ - cache->walked->nelts -= matches; - matches = 0; - } - - if (now_merged) { - now_merged = ap_merge_per_dir_configs(r->pool, - now_merged, - sec_ent[sec_idx]); - } - else { - now_merged = sec_ent[sec_idx]; - } - - last_walk = (walk_walked_t*)apr_array_push(cache->walked); - last_walk->matched = sec_ent[sec_idx]; - last_walk->merged = now_merged; - } - - /* Whoops - everything matched in sequence, but the original walk - * found some additional matches. Truncate them. - */ - if (matches) { - cache->walked->nelts -= matches; - } - } - - cache->dir_conf_tested = sec_ent; - cache->dir_conf_merged = r->per_dir_config; - - /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs, - * and note the end result to (potentially) skip this step next time. - */ - if (now_merged) { - r->per_dir_config = ap_merge_per_dir_configs(r->pool, - r->per_dir_config, - now_merged); - } - cache->per_dir_result = r->per_dir_config; - - return OK; -} - -/***************************************************************** - * - * The sub_request mechanism. - * - * Fns to look up a relative URI from, e.g., a map file or SSI document. - * These do all access checks, etc., but don't actually run the transaction - * ... use run_sub_req below for that. Also, be sure to use destroy_sub_req - * as appropriate if you're likely to be creating more than a few of these. - * (An early Apache version didn't destroy the sub_reqs used in directory - * indexing. The result, when indexing a directory with 800-odd files in - * it, was massively excessive storage allocation). - * - * Note more manipulation of protocol-specific vars in the request - * structure... - */ - -static request_rec *make_sub_request(const request_rec *r, - ap_filter_t *next_filter) -{ - apr_pool_t *rrp; - request_rec *rnew; - - apr_pool_create(&rrp, r->pool); - apr_pool_tag(rrp, "subrequest"); - rnew = apr_pcalloc(rrp, sizeof(request_rec)); - rnew->pool = rrp; - - rnew->hostname = r->hostname; - rnew->request_time = r->request_time; - rnew->connection = r->connection; - rnew->server = r->server; - - rnew->request_config = ap_create_request_config(rnew->pool); - - /* Start a clean config from this subrequest's vhost. Optimization in - * Location/File/Dir walks from the parent request assure that if the - * config blocks of the subrequest match the parent request, no merges - * will actually occur (and generally a minimal number of merges are - * required, even if the parent and subrequest aren't quite identical.) - */ - rnew->per_dir_config = r->server->lookup_defaults; - - rnew->htaccess = r->htaccess; - rnew->allowed_methods = ap_make_method_list(rnew->pool, 2); - - /* make a copy of the allowed-methods list */ - ap_copy_method_list(rnew->allowed_methods, r->allowed_methods); - - /* start with the same set of output filters */ - if (next_filter) { - /* while there are no input filters for a subrequest, we will - * try to insert some, so if we don't have valid data, the code - * will seg fault. - */ - rnew->input_filters = r->input_filters; - rnew->proto_input_filters = r->proto_input_filters; - rnew->output_filters = next_filter; - rnew->proto_output_filters = r->proto_output_filters; - ap_add_output_filter_handle(ap_subreq_core_filter_handle, - NULL, rnew, rnew->connection); - } - else { - /* If NULL - we are expecting to be internal_fast_redirect'ed - * to this subrequest - or this request will never be invoked. - * Ignore the original request filter stack entirely, and - * drill the input and output stacks back to the connection. - */ - rnew->proto_input_filters = r->proto_input_filters; - rnew->proto_output_filters = r->proto_output_filters; - - rnew->input_filters = r->proto_input_filters; - rnew->output_filters = r->proto_output_filters; - } - - /* no input filters for a subrequest */ - - ap_set_sub_req_protocol(rnew, r); - - /* We have to run this after we fill in sub req vars, - * or the r->main pointer won't be setup - */ - ap_run_create_request(rnew); - - return rnew; -} - -AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f, - apr_bucket_brigade *bb) -{ - apr_bucket *e = APR_BRIGADE_LAST(bb); - - if (APR_BUCKET_IS_EOS(e)) { - apr_bucket_delete(e); - } - - if (!APR_BRIGADE_EMPTY(bb)) { - return ap_pass_brigade(f->next, bb); - } - - return APR_SUCCESS; -} - - -AP_DECLARE(int) ap_some_auth_required(request_rec *r) -{ - /* Is there a require line configured for the type of *this* req? */ - - const apr_array_header_t *reqs_arr = ap_requires(r); - require_line *reqs; - int i; - - if (!reqs_arr) { - return 0; - } - - reqs = (require_line *) reqs_arr->elts; - - for (i = 0; i < reqs_arr->nelts; ++i) { - if (reqs[i].method_mask & (AP_METHOD_BIT << r->method_number)) { - return 1; - } - } - - return 0; -} - - -AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method, - const char *new_uri, - const request_rec *r, - ap_filter_t *next_filter) -{ - request_rec *rnew; - int res; - char *udir; - - rnew = make_sub_request(r, next_filter); - - /* would be nicer to pass "method" to ap_set_sub_req_protocol */ - rnew->method = method; - rnew->method_number = ap_method_number_of(method); - - if (new_uri[0] == '/') { - ap_parse_uri(rnew, new_uri); - } - else { - udir = ap_make_dirstr_parent(rnew->pool, r->uri); - udir = ap_escape_uri(rnew->pool, udir); /* re-escape it */ - ap_parse_uri(rnew, ap_make_full_path(rnew->pool, udir, new_uri)); - } - - /* We cannot return NULL without violating the API. So just turn this - * subrequest into a 500 to indicate the failure. */ - if (ap_is_recursion_limit_exceeded(r)) { - rnew->status = HTTP_INTERNAL_SERVER_ERROR; - return rnew; - } - - /* lookup_uri - * If the content can be served by the quick_handler, we can - * safely bypass request_internal processing. - */ - res = ap_run_quick_handler(rnew, 1); - - if (res != OK) { - if ((res = ap_process_request_internal(rnew))) { - rnew->status = res; - } - } - - return rnew; -} - -AP_DECLARE(request_rec *) ap_sub_req_lookup_uri(const char *new_uri, - const request_rec *r, - ap_filter_t *next_filter) -{ - return ap_sub_req_method_uri("GET", new_uri, r, next_filter); -} - -AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *dirent, - const request_rec *r, - int subtype, - ap_filter_t *next_filter) -{ - request_rec *rnew; - int res; - char *fdir; - char *udir; - - rnew = make_sub_request(r, next_filter); - - /* Special case: we are looking at a relative lookup in the same directory. - * This is 100% safe, since dirent->name just came from the filesystem. - */ - if (r->path_info && *r->path_info) { - /* strip path_info off the end of the uri to keep it in sync - * with r->filename, which has already been stripped by directory_walk, - * merge the dirent->name, and then, if the caller wants us to remerge - * the original path info, do so. Note we never fix the path_info back - * to r->filename, since dir_walk would do so (but we don't expect it - * to happen in the usual cases) - */ - udir = apr_pstrdup(rnew->pool, r->uri); - udir[ap_find_path_info(udir, r->path_info)] = '\0'; - udir = ap_make_dirstr_parent(rnew->pool, udir); - - rnew->uri = ap_make_full_path(rnew->pool, udir, dirent->name); - if (subtype == AP_SUBREQ_MERGE_ARGS) { - rnew->uri = ap_make_full_path(rnew->pool, rnew->uri, r->path_info + 1); - rnew->path_info = apr_pstrdup(rnew->pool, r->path_info); - } - rnew->uri = ap_escape_uri(rnew->pool, rnew->uri); - } - else { - udir = ap_make_dirstr_parent(rnew->pool, r->uri); - rnew->uri = ap_escape_uri(rnew->pool, ap_make_full_path(rnew->pool, - udir, - dirent->name)); - } - - fdir = ap_make_dirstr_parent(rnew->pool, r->filename); - rnew->filename = ap_make_full_path(rnew->pool, fdir, dirent->name); - if (r->canonical_filename == r->filename) { - rnew->canonical_filename = rnew->filename; - } - - /* XXX This is now less relevant; we will do a full location walk - * these days for this case. Preserve the apr_stat results, and - * perhaps we also tag that symlinks were tested and/or found for - * r->filename. - */ - rnew->per_dir_config = r->server->lookup_defaults; - - if ((dirent->valid & APR_FINFO_MIN) != APR_FINFO_MIN) { - /* - * apr_dir_read isn't very complete on this platform, so - * we need another apr_lstat (or simply apr_stat if we allow - * all symlinks here.) If this is an APR_LNK that resolves - * to an APR_DIR, then we will rerun everything anyways... - * this should be safe. - */ - apr_status_t rv; - if (ap_allow_options(rnew) & OPT_SYM_LINKS) { - if (((rv = apr_stat(&rnew->finfo, rnew->filename, - APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) - && (rv != APR_INCOMPLETE)) { - rnew->finfo.filetype = 0; - } - } - else { - if (((rv = apr_lstat(&rnew->finfo, rnew->filename, - APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) - && (rv != APR_INCOMPLETE)) { - rnew->finfo.filetype = 0; - } - } - } - else { - memcpy(&rnew->finfo, dirent, sizeof(apr_finfo_t)); - } - - if (rnew->finfo.filetype == APR_LNK) { - /* - * Resolve this symlink. We should tie this back to dir_walk's cache - */ - if ((res = resolve_symlink(rnew->filename, &rnew->finfo, - ap_allow_options(rnew), rnew->pool)) - != OK) { - rnew->status = res; - return rnew; - } - } - - if (rnew->finfo.filetype == APR_DIR) { - /* ap_make_full_path overallocated the buffers - * by one character to help us out here. - */ - strcpy(rnew->filename + strlen(rnew->filename), "/"); - if (!rnew->path_info || !*rnew->path_info) { - strcpy(rnew->uri + strlen(rnew->uri ), "/"); - } - } - - /* fill in parsed_uri values - */ - if (r->args && *r->args && (subtype == AP_SUBREQ_MERGE_ARGS)) { - ap_parse_uri(rnew, apr_pstrcat(r->pool, rnew->uri, "?", - r->args, NULL)); - } - else { - ap_parse_uri(rnew, rnew->uri); - } - - /* We cannot return NULL without violating the API. So just turn this - * subrequest into a 500. */ - if (ap_is_recursion_limit_exceeded(r)) { - rnew->status = HTTP_INTERNAL_SERVER_ERROR; - return rnew; - } - - if ((res = ap_process_request_internal(rnew))) { - rnew->status = res; - } - - return rnew; -} - -AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, - const request_rec *r, - ap_filter_t *next_filter) -{ - request_rec *rnew; - int res; - char *fdir; - apr_size_t fdirlen; - - rnew = make_sub_request(r, next_filter); - - fdir = ap_make_dirstr_parent(rnew->pool, r->filename); - fdirlen = strlen(fdir); - - /* Translate r->filename, if it was canonical, it stays canonical - */ - if (r->canonical_filename == r->filename) { - rnew->canonical_filename = (char*)(1); - } - - if (apr_filepath_merge(&rnew->filename, fdir, new_file, - APR_FILEPATH_TRUENAME, rnew->pool) != APR_SUCCESS) { - rnew->status = HTTP_FORBIDDEN; - return rnew; - } - - if (rnew->canonical_filename) { - rnew->canonical_filename = rnew->filename; - } - - /* - * Check for a special case... if there are no '/' characters in new_file - * at all, and the path was the same, then we are looking at a relative - * lookup in the same directory. Fixup the URI to match. - */ - - if (strncmp(rnew->filename, fdir, fdirlen) == 0 - && rnew->filename[fdirlen] - && ap_strchr_c(rnew->filename + fdirlen, '/') == NULL) { - apr_status_t rv; - if (ap_allow_options(rnew) & OPT_SYM_LINKS) { - if (((rv = apr_stat(&rnew->finfo, rnew->filename, - APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) - && (rv != APR_INCOMPLETE)) { - rnew->finfo.filetype = 0; - } - } - else { - if (((rv = apr_lstat(&rnew->finfo, rnew->filename, - APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) - && (rv != APR_INCOMPLETE)) { - rnew->finfo.filetype = 0; - } - } - - if (r->uri && *r->uri) { - char *udir = ap_make_dirstr_parent(rnew->pool, r->uri); - rnew->uri = ap_make_full_path(rnew->pool, udir, - rnew->filename + fdirlen); - ap_parse_uri(rnew, rnew->uri); /* fill in parsed_uri values */ - } - else { - ap_parse_uri(rnew, new_file); /* fill in parsed_uri values */ - rnew->uri = apr_pstrdup(rnew->pool, ""); - } - } - else { - /* XXX: @@@: What should be done with the parsed_uri values? - * We would be better off stripping down to the 'common' elements - * of the path, then reassembling the URI as best as we can. - */ - ap_parse_uri(rnew, new_file); /* fill in parsed_uri values */ - /* - * XXX: this should be set properly like it is in the same-dir case - * but it's actually sometimes to impossible to do it... because the - * file may not have a uri associated with it -djg - */ - rnew->uri = apr_pstrdup(rnew->pool, ""); - } - - /* We cannot return NULL without violating the API. So just turn this - * subrequest into a 500. */ - if (ap_is_recursion_limit_exceeded(r)) { - rnew->status = HTTP_INTERNAL_SERVER_ERROR; - return rnew; - } - - if ((res = ap_process_request_internal(rnew))) { - rnew->status = res; - } - - return rnew; -} - -AP_DECLARE(int) ap_run_sub_req(request_rec *r) -{ - int retval = DECLINED; - /* Run the quick handler if the subrequest is not a dirent or file - * subrequest - */ - if (!(r->filename && r->finfo.filetype)) { - retval = ap_run_quick_handler(r, 0); - } - if (retval != OK) { - retval = ap_invoke_handler(r); - if (retval == DONE) { - retval = OK; - } - } - ap_finalize_sub_req_protocol(r); - return retval; -} - -AP_DECLARE(void) ap_destroy_sub_req(request_rec *r) -{ - /* Reclaim the space */ - apr_pool_destroy(r->pool); -} - -/* - * Function to set the r->mtime field to the specified value if it's later - * than what's already there. - */ -AP_DECLARE(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime) -{ - if (r->mtime < dependency_mtime) { - r->mtime = dependency_mtime; - } -} - -/* - * Is it the initial main request, which we only get *once* per HTTP request? - */ -AP_DECLARE(int) ap_is_initial_req(request_rec *r) -{ - return (r->main == NULL) /* otherwise, this is a sub-request */ - && (r->prev == NULL); /* otherwise, this is an internal redirect */ -} diff --git a/rubbos/app/httpd-2.0.64/server/request.lo b/rubbos/app/httpd-2.0.64/server/request.lo deleted file mode 100644 index e7751975..00000000 --- a/rubbos/app/httpd-2.0.64/server/request.lo +++ /dev/null @@ -1,12 +0,0 @@ -# request.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/request.o' - -# Name of the non-PIC object. -non_pic_object='request.o' - diff --git a/rubbos/app/httpd-2.0.64/server/request.o b/rubbos/app/httpd-2.0.64/server/request.o Binary files differdeleted file mode 100644 index 136bd10a..00000000 --- a/rubbos/app/httpd-2.0.64/server/request.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/rfc1413.c b/rubbos/app/httpd-2.0.64/server/rfc1413.c deleted file mode 100644 index 755bd917..00000000 --- a/rubbos/app/httpd-2.0.64/server/rfc1413.c +++ /dev/null @@ -1,243 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* TODO - put timeouts back in */ -/* - * rfc1413() speaks a common subset of the RFC 1413, AUTH, TAP and IDENT - * protocols. The code queries an RFC 1413 etc. compatible daemon on a remote - * host to look up the owner of a connection. The information should not be - * used for authentication purposes. This routine intercepts alarm signals. - * - * Diagnostics are reported through syslog(3). - * - * Author: Wietse Venema, Eindhoven University of Technology, - * The Netherlands. - */ - -/* Some small additions for Apache --- ditch the "sccsid" var if - * compiling with gcc (it *has* changed), include ap_config.h for the - * prototypes it defines on at least one system (SunlOSs) which has - * them missing from the standard header files, and one minor change - * below (extra parens around assign "if (foo = bar) ..." to shut up - * gcc -Wall). - */ - -/* Rewritten by David Robinson */ - -#include "apr.h" -#include "apr_network_io.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_inherit.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "ap_config.h" -#include "httpd.h" /* for server_rec, conn_rec, etc. */ -#include "http_log.h" /* for aplog_error */ -#include "rfc1413.h" -#include "http_main.h" /* set_callback_and_alarm */ -#include "util_ebcdic.h" - -/* Local stuff. */ -/* Semi-well-known port */ -#define RFC1413_PORT 113 -/* maximum allowed length of userid */ -#define RFC1413_USERLEN 512 -/* rough limit on the amount of data we accept. */ -#define RFC1413_MAXDATA 1000 - -#ifndef RFC1413_TIMEOUT -#define RFC1413_TIMEOUT 30 -#endif -#define FROM_UNKNOWN "unknown" - -int ap_rfc1413_timeout = RFC1413_TIMEOUT; /* Global so it can be changed */ - -static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, - server_rec *srv) -{ - apr_status_t rv; - apr_sockaddr_t *localsa, *destsa; - - if ((rv = apr_sockaddr_info_get(&localsa, conn->local_ip, APR_UNSPEC, - 0, /* ephemeral port */ - 0, conn->pool)) != APR_SUCCESS) { - /* This should not fail since we have a numeric address string - * as the host. */ - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, - "rfc1413: apr_sockaddr_info_get(%s) failed", - conn->local_ip); - return rv; - } - - if ((rv = apr_sockaddr_info_get(&destsa, conn->remote_ip, - localsa->family, /* has to match */ - RFC1413_PORT, 0, conn->pool)) != APR_SUCCESS) { - /* This should not fail since we have a numeric address string - * as the host. */ - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, - "rfc1413: apr_sockaddr_info_get(%s) failed", - conn->remote_ip); - return rv; - } - - if ((rv = apr_socket_create(newsock, - localsa->family, /* has to match */ - SOCK_STREAM, conn->pool)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, - "rfc1413: error creating query socket"); - return rv; - } - - if ((rv = apr_socket_timeout_set(*newsock, apr_time_from_sec(ap_rfc1413_timeout))) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, - "rfc1413: error setting query socket timeout"); - apr_socket_close(*newsock); - return rv; - } - -/* - * Bind the local and remote ends of the query socket to the same - * IP addresses as the connection under investigation. We go - * through all this trouble because the local or remote system - * might have more than one network address. The RFC1413 etc. - * client sends only port numbers; the server takes the IP - * addresses from the query socket. - */ - - if ((rv = apr_bind(*newsock, localsa)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, - "rfc1413: Error binding query socket to local port"); - apr_socket_close(*newsock); - return rv; - } - -/* - * errors from connect usually imply the remote machine doesn't support - * the service; don't log such an error - */ - if ((rv = apr_connect(*newsock, destsa)) != APR_SUCCESS) { - apr_socket_close(*newsock); - return rv; - } - - return APR_SUCCESS; -} - -static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, - server_rec *srv) -{ - apr_port_t rmt_port, our_port; - apr_port_t sav_rmt_port, sav_our_port; - apr_size_t i; - char *cp; - char buffer[RFC1413_MAXDATA + 1]; - char user[RFC1413_USERLEN + 1]; /* XXX */ - apr_size_t buflen; - - apr_sockaddr_port_get(&sav_our_port, conn->local_addr); - apr_sockaddr_port_get(&sav_rmt_port, conn->remote_addr); - - /* send the data */ - buflen = apr_snprintf(buffer, sizeof(buffer), "%hu,%hu\r\n", sav_rmt_port, - sav_our_port); - ap_xlate_proto_to_ascii(buffer, buflen); - - /* send query to server. Handle short write. */ - i = 0; - while (i < buflen) { - apr_size_t j = strlen(buffer + i); - apr_status_t status; - status = apr_send(sock, buffer+i, &j); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, - "write: rfc1413: error sending request"); - return status; - } - else if (j > 0) { - i+=j; - } - } - - /* - * Read response from server. - the response should be newline - * terminated according to rfc - make sure it doesn't stomp its - * way out of the buffer. - */ - - i = 0; - memset(buffer, '\0', sizeof(buffer)); - /* - * Note that the strchr function below checks for \012 instead of '\n' - * this allows it to work on both ASCII and EBCDIC machines. - */ - while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) { - apr_size_t j = sizeof(buffer) - 1 - i; - apr_status_t status; - status = apr_recv(sock, buffer+i, &j); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, - "read: rfc1413: error reading response"); - return status; - } - else if (j > 0) { - i+=j; - } - else if (status == APR_SUCCESS && j == 0) { - /* Oops... we ran out of data before finding newline */ - return APR_EINVAL; - } - } - -/* RFC1413_USERLEN = 512 */ - ap_xlate_proto_from_ascii(buffer, i); - if (sscanf(buffer, "%hu , %hu : USERID :%*[^:]:%512s", &rmt_port, &our_port, - user) != 3 || sav_rmt_port != rmt_port - || sav_our_port != our_port) - return APR_EINVAL; - - /* - * Strip trailing carriage return. It is part of the - * protocol, not part of the data. - */ - - if ((cp = strchr(user, '\r'))) - *cp = '\0'; - - conn->remote_logname = apr_pstrdup(conn->pool, user); - - return APR_SUCCESS; -} - -char *ap_rfc1413(conn_rec *conn, server_rec *srv) -{ - apr_socket_t *sock; - apr_status_t rv; - - rv = rfc1413_connect(&sock, conn, srv); - if (rv == APR_SUCCESS) { - rv = rfc1413_query(sock, conn, srv); - apr_socket_close(sock); - } - if (rv != APR_SUCCESS) { - conn->remote_logname = FROM_UNKNOWN; - } - return conn->remote_logname; -} diff --git a/rubbos/app/httpd-2.0.64/server/rfc1413.lo b/rubbos/app/httpd-2.0.64/server/rfc1413.lo deleted file mode 100644 index e25fa9a1..00000000 --- a/rubbos/app/httpd-2.0.64/server/rfc1413.lo +++ /dev/null @@ -1,12 +0,0 @@ -# rfc1413.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/rfc1413.o' - -# Name of the non-PIC object. -non_pic_object='rfc1413.o' - diff --git a/rubbos/app/httpd-2.0.64/server/rfc1413.o b/rubbos/app/httpd-2.0.64/server/rfc1413.o Binary files differdeleted file mode 100644 index 04b1ff54..00000000 --- a/rubbos/app/httpd-2.0.64/server/rfc1413.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/scoreboard.c b/rubbos/app/httpd-2.0.64/server/scoreboard.c deleted file mode 100644 index c0b0ed05..00000000 --- a/rubbos/app/httpd-2.0.64/server/scoreboard.c +++ /dev/null @@ -1,465 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_portable.h" -#include "apr_lib.h" - -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#include "ap_config.h" -#include "httpd.h" -#include "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_config.h" -#include "ap_mpm.h" - -#include "mpm.h" -#include "scoreboard.h" - -AP_DECLARE_DATA scoreboard *ap_scoreboard_image = NULL; -AP_DECLARE_DATA const char *ap_scoreboard_fname = NULL; -AP_DECLARE_DATA int ap_extended_status = 0; - -#if APR_HAS_SHARED_MEMORY - -#include "apr_shm.h" - -#ifndef WIN32 -static /* but must be exported to mpm_winnt */ -#endif - apr_shm_t *ap_scoreboard_shm = NULL; - -#endif - -APR_HOOK_STRUCT( - APR_HOOK_LINK(pre_mpm) -) - -AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_mpm, - (apr_pool_t *p, ap_scoreboard_e sb_type), - (p, sb_type),OK,DECLINED) - -struct ap_sb_handle_t { - int child_num; - int thread_num; -}; - -static int server_limit, thread_limit; -static apr_size_t scoreboard_size; - -/* - * ToDo: - * This function should be renamed to cleanup_shared - * and it should handle cleaning up a scoreboard shared - * between processes using any form of IPC (file, shared memory - * segment, etc.). Leave it as is now because it is being used - * by various MPMs. - */ -static apr_status_t ap_cleanup_shared_mem(void *d) -{ -#if APR_HAS_SHARED_MEMORY - free(ap_scoreboard_image); - ap_scoreboard_image = NULL; - apr_shm_destroy(ap_scoreboard_shm); -#endif - return APR_SUCCESS; -} - -AP_DECLARE(int) ap_calc_scoreboard_size(void) -{ - ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); - ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit); - scoreboard_size = sizeof(global_score); - scoreboard_size += sizeof(process_score) * server_limit; - scoreboard_size += sizeof(worker_score) * server_limit * thread_limit; - return scoreboard_size; -} - -void ap_init_scoreboard(void *shared_score) -{ - char *more_storage; - int i; - - ap_calc_scoreboard_size(); - ap_scoreboard_image = - calloc(1, sizeof(scoreboard) + server_limit * sizeof(worker_score *)); - more_storage = shared_score; - ap_scoreboard_image->global = (global_score *)more_storage; - more_storage += sizeof(global_score); - ap_scoreboard_image->parent = (process_score *)more_storage; - more_storage += sizeof(process_score) * server_limit; - ap_scoreboard_image->servers = - (worker_score **)((char*)ap_scoreboard_image + sizeof(scoreboard)); - for (i = 0; i < server_limit; i++) { - ap_scoreboard_image->servers[i] = (worker_score *)more_storage; - more_storage += thread_limit * sizeof(worker_score); - } - ap_assert(more_storage == (char*)shared_score + scoreboard_size); - ap_scoreboard_image->global->server_limit = server_limit; - ap_scoreboard_image->global->thread_limit = thread_limit; -} - -/** - * Create a name-based scoreboard in the given pool using the - * given filename. - */ -static apr_status_t create_namebased_scoreboard(apr_pool_t *pool, - const char *fname) -{ -#if APR_HAS_SHARED_MEMORY - apr_status_t rv; - - /* The shared memory file must not exist before we create the - * segment. */ - apr_file_remove(fname, pool); /* ignore errors */ - - rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, pool); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "unable to create scoreboard \"%s\" " - "(name-based shared memory failure)", fname); - return rv; - } -#endif /* APR_HAS_SHARED_MEMORY */ - return APR_SUCCESS; -} - -/* ToDo: This function should be made to handle setting up - * a scoreboard shared between processes using any IPC technique, - * not just a shared memory segment - */ -static apr_status_t open_scoreboard(apr_pool_t *pconf) -{ -#if APR_HAS_SHARED_MEMORY - apr_status_t rv; - char *fname = NULL; - apr_pool_t *global_pool; - - /* We don't want to have to recreate the scoreboard after - * restarts, so we'll create a global pool and never clean it. - */ - rv = apr_pool_create(&global_pool, NULL); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Fatal error: unable to create global pool " - "for use with by the scoreboard"); - return rv; - } - - /* The config says to create a name-based shmem */ - if (ap_scoreboard_fname) { - /* make sure it's an absolute pathname */ - fname = ap_server_root_relative(pconf, ap_scoreboard_fname); - if (!fname) { - ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EBADPATH, NULL, - "Fatal error: Invalid Scoreboard path %s", - ap_scoreboard_fname); - return APR_EBADPATH; - } - return create_namebased_scoreboard(global_pool, fname); - } - else { /* config didn't specify, we get to choose shmem type */ - rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, NULL, - global_pool); /* anonymous shared memory */ - if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Unable to create scoreboard " - "(anonymous shared memory failure)"); - return rv; - } - /* Make up a filename and do name-based shmem */ - else if (rv == APR_ENOTIMPL) { - /* Make sure it's an absolute pathname */ - ap_scoreboard_fname = DEFAULT_SCOREBOARD; - fname = ap_server_root_relative(pconf, ap_scoreboard_fname); - - return create_namebased_scoreboard(global_pool, fname); - } - } -#endif /* APR_HAS_SHARED_MEMORY */ - return APR_SUCCESS; -} - -/* If detach is non-zero, this is a seperate child process, - * if zero, it is a forked child. - */ -apr_status_t ap_reopen_scoreboard(apr_pool_t *p, apr_shm_t **shm, int detached) -{ -#if APR_HAS_SHARED_MEMORY - if (!detached) { - return APR_SUCCESS; - } - if (apr_shm_size_get(ap_scoreboard_shm) < scoreboard_size) { - ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, - "Fatal error: shared scoreboard too small for child!"); - apr_shm_detach(ap_scoreboard_shm); - ap_scoreboard_shm = NULL; - return APR_EINVAL; - } - /* everything will be cleared shortly */ - if (*shm) { - *shm = ap_scoreboard_shm; - } -#endif - return APR_SUCCESS; -} - -apr_status_t ap_cleanup_scoreboard(void *d) -{ - if (ap_scoreboard_image == NULL) { - return APR_SUCCESS; - } - if (ap_scoreboard_image->global->sb_type == SB_SHARED) { - ap_cleanup_shared_mem(NULL); - } - else { - free(ap_scoreboard_image->global); - free(ap_scoreboard_image); - ap_scoreboard_image = NULL; - } - return APR_SUCCESS; -} - -/* Create or reinit an existing scoreboard. The MPM can control whether - * the scoreboard is shared across multiple processes or not - */ -int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) -{ - int running_gen = 0; - int i; -#if APR_HAS_SHARED_MEMORY - apr_status_t rv; -#endif - - if (ap_scoreboard_image) { - running_gen = ap_scoreboard_image->global->running_generation; - ap_scoreboard_image->global->restart_time = apr_time_now(); - memset(ap_scoreboard_image->parent, 0, - sizeof(process_score) * server_limit); - for (i = 0; i < server_limit; i++) { - memset(ap_scoreboard_image->servers[i], 0, - sizeof(worker_score) * thread_limit); - } - return OK; - } - - ap_calc_scoreboard_size(); -#if APR_HAS_SHARED_MEMORY - if (sb_type == SB_SHARED) { - void *sb_shared; - rv = open_scoreboard(p); - if (rv || !(sb_shared = apr_shm_baseaddr_get(ap_scoreboard_shm))) { - return HTTP_INTERNAL_SERVER_ERROR; - } - memset(sb_shared, 0, scoreboard_size); - ap_init_scoreboard(sb_shared); - } - else -#endif - { - /* A simple malloc will suffice */ - void *sb_mem = calloc(1, scoreboard_size); - if (sb_mem == NULL) { - ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, - "(%d)%s: cannot allocate scoreboard", - errno, strerror(errno)); - return HTTP_INTERNAL_SERVER_ERROR; - } - ap_init_scoreboard(sb_mem); - } - - ap_scoreboard_image->global->sb_type = sb_type; - ap_scoreboard_image->global->running_generation = running_gen; - ap_scoreboard_image->global->restart_time = apr_time_now(); - - apr_pool_cleanup_register(p, NULL, ap_cleanup_scoreboard, apr_pool_cleanup_null); - - return OK; -} - -/* Routines called to deal with the scoreboard image - * --- note that we do *not* need write locks, since update_child_status - * only updates a *single* record in place, and only one process writes to - * a given scoreboard slot at a time (either the child process owning that - * slot, or the parent, noting that the child has died). - * - * As a final note --- setting the score entry to getpid() is always safe, - * since when the parent is writing an entry, it's only noting SERVER_DEAD - * anyway. - */ - -AP_DECLARE(int) ap_exists_scoreboard_image(void) -{ - return (ap_scoreboard_image ? 1 : 0); -} - -AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sb, request_rec *r) -{ - worker_score *ws; - - ws = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num]; - -#ifdef HAVE_TIMES - times(&ws->times); -#endif - ws->access_count++; - ws->my_access_count++; - ws->conn_count++; - ws->bytes_served += r->bytes_sent; - ws->my_bytes_served += r->bytes_sent; - ws->conn_bytes += r->bytes_sent; -} - -AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid) -{ - int i; - int max_daemons_limit; - - ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_daemons_limit); - - for (i = 0; i < max_daemons_limit; ++i) { - if (ap_scoreboard_image->parent[i].pid == pid->pid) { - return i; - } - } - - return -1; -} - -AP_DECLARE(void) ap_create_sb_handle(ap_sb_handle_t **new_sbh, apr_pool_t *p, - int child_num, int thread_num) -{ - *new_sbh = (ap_sb_handle_t *)apr_palloc(p, sizeof(ap_sb_handle_t)); - (*new_sbh)->child_num = child_num; - (*new_sbh)->thread_num = thread_num; -} - -AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, - int thread_num, - int status, - request_rec *r) -{ - int old_status; - worker_score *ws; - process_score *ps; - - if (child_num < 0) { - return -1; - } - - ws = &ap_scoreboard_image->servers[child_num][thread_num]; - old_status = ws->status; - ws->status = status; - - ps = &ap_scoreboard_image->parent[child_num]; - - if (status == SERVER_READY - && old_status == SERVER_STARTING) { - ws->thread_num = child_num * thread_limit + thread_num; - ps->generation = ap_my_generation; - } - - if (ap_extended_status) { - ws->last_used = apr_time_now(); - if (status == SERVER_READY || status == SERVER_DEAD) { - /* - * Reset individual counters - */ - if (status == SERVER_DEAD) { - ws->my_access_count = 0L; - ws->my_bytes_served = 0L; - } - ws->conn_count = 0; - ws->conn_bytes = 0; - } - if (r) { - conn_rec *c = r->connection; - apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config, - REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); - if (r->the_request == NULL) { - apr_cpystrn(ws->request, "NULL", sizeof(ws->request)); - } else if (r->parsed_uri.password == NULL) { - apr_cpystrn(ws->request, r->the_request, sizeof(ws->request)); - } else { - /* Don't reveal the password in the server-status view */ - apr_cpystrn(ws->request, apr_pstrcat(r->pool, r->method, " ", - apr_uri_unparse(r->pool, &r->parsed_uri, - APR_URI_UNP_OMITPASSWORD), - r->assbackwards ? NULL : " ", r->protocol, NULL), - sizeof(ws->request)); - } - apr_cpystrn(ws->vhost, r->server->server_hostname, - sizeof(ws->vhost)); - } - } - - return old_status; -} - -AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status, - request_rec *r) -{ - return ap_update_child_status_from_indexes(sbh->child_num, sbh->thread_num, - status, r); -} - -void ap_time_process_request(ap_sb_handle_t *sbh, int status) -{ - worker_score *ws; - - if (sbh->child_num < 0) { - return; - } - - ws = &ap_scoreboard_image->servers[sbh->child_num][sbh->thread_num]; - - if (status == START_PREQUEST) { - ws->start_time = apr_time_now(); - } - else if (status == STOP_PREQUEST) { - ws->stop_time = apr_time_now(); - } -} - -AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y) -{ - if (((x < 0) || (server_limit < x)) || - ((y < 0) || (thread_limit < y))) { - return(NULL); /* Out of range */ - } - return &ap_scoreboard_image->servers[x][y]; -} - -AP_DECLARE(process_score *) ap_get_scoreboard_process(int x) -{ - if ((x < 0) || (server_limit < x)) { - return(NULL); /* Out of range */ - } - return &ap_scoreboard_image->parent[x]; -} - -AP_DECLARE(global_score *) ap_get_scoreboard_global() -{ - return ap_scoreboard_image->global; -} diff --git a/rubbos/app/httpd-2.0.64/server/scoreboard.lo b/rubbos/app/httpd-2.0.64/server/scoreboard.lo deleted file mode 100644 index 3a2d5065..00000000 --- a/rubbos/app/httpd-2.0.64/server/scoreboard.lo +++ /dev/null @@ -1,12 +0,0 @@ -# scoreboard.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/scoreboard.o' - -# Name of the non-PIC object. -non_pic_object='scoreboard.o' - diff --git a/rubbos/app/httpd-2.0.64/server/scoreboard.o b/rubbos/app/httpd-2.0.64/server/scoreboard.o Binary files differdeleted file mode 100644 index 58be9313..00000000 --- a/rubbos/app/httpd-2.0.64/server/scoreboard.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/test_char.h b/rubbos/app/httpd-2.0.64/server/test_char.h deleted file mode 100644 index fe168495..00000000 --- a/rubbos/app/httpd-2.0.64/server/test_char.h +++ /dev/null @@ -1,23 +0,0 @@ -/* this file is automatically generated by gen_test_char, do not edit */ -#define T_ESCAPE_SHELL_CMD (1) -#define T_ESCAPE_PATH_SEGMENT (2) -#define T_OS_ESCAPE_PATH (4) -#define T_HTTP_TOKEN_STOP (8) -#define T_ESCAPE_LOGITEM (16) -#define T_ESCAPE_FORENSIC (32) - -static const unsigned char test_char_table[256] = { - 0,62,62,62,62,62,62,62,62,62,63,62,62,62,62,62,62,62,62,62, - 62,62,62,62,62,62,62,62,62,62,62,62,14,0,23,6,1,38,1,1, - 9,9,1,0,8,0,0,10,0,0,0,0,0,0,0,0,0,0,40,15, - 15,8,15,15,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,15,31,15,7,0,7,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,15,39,15,1,62,54,54,54,54,54,54,54,54,54,54,54,54, - 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, - 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, - 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, - 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, - 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, - 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54 -}; diff --git a/rubbos/app/httpd-2.0.64/server/util.c b/rubbos/app/httpd-2.0.64/server/util.c deleted file mode 100644 index a64f3bf9..00000000 --- a/rubbos/app/httpd-2.0.64/server/util.c +++ /dev/null @@ -1,2170 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * util.c: string utility things - * - * 3/21/93 Rob McCool - * 1995-96 Many changes by the Apache Software Foundation - * - */ - -/* Debugging aid: - * #define DEBUG to trace all cfg_open*()/cfg_closefile() calls - * #define DEBUG_CFG_LINES to trace every line read from the config files - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_lib.h" - -#define APR_WANT_STDIO -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_NETDB_H -#include <netdb.h> /* for gethostbyname() */ -#endif - -#define CORE_PRIVATE - -#include "ap_config.h" -#include "apr_base64.h" -#include "httpd.h" -#include "http_main.h" -#include "http_log.h" -#include "http_protocol.h" -#include "http_config.h" -#include "util_ebcdic.h" - -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif -#ifdef HAVE_GRP_H -#include <grp.h> -#endif - -/* A bunch of functions in util.c scan strings looking for certain characters. - * To make that more efficient we encode a lookup table. The test_char_table - * is generated automatically by gen_test_char.c. - */ -#include "test_char.h" - -/* we assume the folks using this ensure 0 <= c < 256... which means - * you need a cast to (unsigned char) first, you can't just plug a - * char in here and get it to work, because if char is signed then it - * will first be sign extended. - */ -#define TEST_CHAR(c, f) (test_char_table[(unsigned)(c)] & (f)) - -/* Win32/NetWare/OS2 need to check for both forward and back slashes - * in ap_getparents() and ap_escape_url. - */ -#ifdef CASE_BLIND_FILESYSTEM -#define IS_SLASH(s) ((s == '/') || (s == '\\')) -#else -#define IS_SLASH(s) (s == '/') -#endif - - -/* - * Examine a field value (such as a media-/content-type) string and return - * it sans any parameters; e.g., strip off any ';charset=foo' and the like. - */ -AP_DECLARE(char *) ap_field_noparam(apr_pool_t *p, const char *intype) -{ - const char *semi; - - if (intype == NULL) return NULL; - - semi = ap_strchr_c(intype, ';'); - if (semi == NULL) { - return apr_pstrdup(p, intype); - } - else { - while ((semi > intype) && apr_isspace(semi[-1])) { - semi--; - } - return apr_pstrndup(p, intype, semi - intype); - } -} - -AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt, - int gmt) -{ - apr_size_t retcode; - char ts[MAX_STRING_LEN]; - char tf[MAX_STRING_LEN]; - apr_time_exp_t xt; - - if (gmt) { - const char *f; - char *strp; - - apr_time_exp_gmt(&xt, t); - /* Convert %Z to "GMT" and %z to "+0000"; - * on hosts that do not have a time zone string in struct tm, - * strftime must assume its argument is local time. - */ - for(strp = tf, f = fmt; strp < tf + sizeof(tf) - 6 && (*strp = *f) - ; f++, strp++) { - if (*f != '%') continue; - switch (f[1]) { - case '%': - *++strp = *++f; - break; - case 'Z': - *strp++ = 'G'; - *strp++ = 'M'; - *strp = 'T'; - f++; - break; - case 'z': /* common extension */ - *strp++ = '+'; - *strp++ = '0'; - *strp++ = '0'; - *strp++ = '0'; - *strp = '0'; - f++; - break; - } - } - *strp = '\0'; - fmt = tf; - } - else { - apr_time_exp_lt(&xt, t); - } - - /* check return code? */ - apr_strftime(ts, &retcode, MAX_STRING_LEN, fmt, &xt); - ts[MAX_STRING_LEN - 1] = '\0'; - return apr_pstrdup(p, ts); -} - -/* Roy owes Rob beer. */ -/* Rob owes Roy dinner. */ - -/* These legacy comments would make a lot more sense if Roy hadn't - * replaced the old later_than() routine with util_date.c. - * - * Well, okay, they still wouldn't make any sense. - */ - -/* Match = 0, NoMatch = 1, Abort = -1 - * Based loosely on sections of wildmat.c by Rich Salz - * Hmmm... shouldn't this really go component by component? - */ -AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected) -{ - int x, y; - - for (x = 0, y = 0; expected[y]; ++y, ++x) { - if ((!str[x]) && (expected[y] != '*')) - return -1; - if (expected[y] == '*') { - while (expected[++y] == '*'); - if (!expected[y]) - return 0; - while (str[x]) { - int ret; - if ((ret = ap_strcmp_match(&str[x++], &expected[y])) != 1) - return ret; - } - return -1; - } - else if ((expected[y] != '?') && (str[x] != expected[y])) - return 1; - } - return (str[x] != '\0'); -} - -AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected) -{ - int x, y; - - for (x = 0, y = 0; expected[y]; ++y, ++x) { - if (!str[x] && expected[y] != '*') - return -1; - if (expected[y] == '*') { - while (expected[++y] == '*'); - if (!expected[y]) - return 0; - while (str[x]) { - int ret; - if ((ret = ap_strcasecmp_match(&str[x++], &expected[y])) != 1) - return ret; - } - return -1; - } - else if (expected[y] != '?' - && apr_tolower(str[x]) != apr_tolower(expected[y])) - return 1; - } - return (str[x] != '\0'); -} - -/* We actually compare the canonical root to this root, (but we don't - * waste time checking the case), since every use of this function in - * httpd-2.0 tests if the path is 'proper', meaning we've already passed - * it through apr_filepath_merge, or we haven't. - */ -AP_DECLARE(int) ap_os_is_path_absolute(apr_pool_t *p, const char *dir) -{ - const char *newpath; - const char *ourdir = dir; - if (apr_filepath_root(&newpath, &dir, 0, p) != APR_SUCCESS - || strncmp(newpath, ourdir, strlen(newpath)) != 0) { - return 0; - } - return 1; -} - -AP_DECLARE(int) ap_is_matchexp(const char *str) -{ - register int x; - - for (x = 0; str[x]; x++) - if ((str[x] == '*') || (str[x] == '?')) - return 1; - return 0; -} - -/* - * Here's a pool-based interface to POSIX regex's regcomp(). - * Note that we return regex_t instead of being passed one. - * The reason is that if you use an already-used regex_t structure, - * the memory that you've already allocated gets forgotten, and - * regfree() doesn't clear it. So we don't allow it. - */ - -static apr_status_t regex_cleanup(void *preg) -{ - regfree((regex_t *) preg); - return APR_SUCCESS; -} - -AP_DECLARE(regex_t *) ap_pregcomp(apr_pool_t *p, const char *pattern, - int cflags) -{ - regex_t *preg = apr_palloc(p, sizeof(regex_t)); - - if (regcomp(preg, pattern, cflags)) { - return NULL; - } - - apr_pool_cleanup_register(p, (void *) preg, regex_cleanup, - apr_pool_cleanup_null); - - return preg; -} - -AP_DECLARE(void) ap_pregfree(apr_pool_t *p, regex_t * reg) -{ - regfree(reg); - apr_pool_cleanup_kill(p, (void *) reg, regex_cleanup); -} - -/* - * Similar to standard strstr() but we ignore case in this version. - * Based on the strstr() implementation further below. - */ -AP_DECLARE(char *) ap_strcasestr(const char *s1, const char *s2) -{ - char *p1, *p2; - if (*s2 == '\0') { - /* an empty s2 */ - return((char *)s1); - } - while(1) { - for ( ; (*s1 != '\0') && (apr_tolower(*s1) != apr_tolower(*s2)); s1++); - if (*s1 == '\0') { - return(NULL); - } - /* found first character of s2, see if the rest matches */ - p1 = (char *)s1; - p2 = (char *)s2; - for (++p1, ++p2; apr_tolower(*p1) == apr_tolower(*p2); ++p1, ++p2) { - if (*p1 == '\0') { - /* both strings ended together */ - return((char *)s1); - } - } - if (*p2 == '\0') { - /* second string ended, a match */ - break; - } - /* didn't find a match here, try starting at next character in s1 */ - s1++; - } - return((char *)s1); -} - -/* - * Returns an offsetted pointer in bigstring immediately after - * prefix. Returns bigstring if bigstring doesn't start with - * prefix or if prefix is longer than bigstring while still matching. - * NOTE: pointer returned is relative to bigstring, so we - * can use standard pointer comparisons in the calling function - * (eg: test if ap_stripprefix(a,b) == a) - */ -AP_DECLARE(const char *) ap_stripprefix(const char *bigstring, - const char *prefix) -{ - const char *p1; - - if (*prefix == '\0') - return bigstring; - - p1 = bigstring; - while (*p1 && *prefix) { - if (*p1++ != *prefix++) - return bigstring; - } - if (*prefix == '\0') - return p1; - - /* hit the end of bigstring! */ - return bigstring; -} - -/* - * Apache stub function for the regex libraries regexec() to make sure the - * whole regex(3) API is available through the Apache (exported) namespace. - * This is especially important for the DSO situations of modules. - * DO NOT MAKE A MACRO OUT OF THIS FUNCTION! - */ -AP_DECLARE(int) ap_regexec(regex_t *preg, const char *string, - size_t nmatch, regmatch_t pmatch[], int eflags) -{ - return regexec(preg, string, nmatch, pmatch, eflags); -} - -AP_DECLARE(size_t) ap_regerror(int errcode, const regex_t *preg, char *errbuf, - size_t errbuf_size) -{ - return regerror(errcode, preg, errbuf, errbuf_size); -} - - -/* This function substitutes for $0-$9, filling in regular expression - * submatches. Pass it the same nmatch and pmatch arguments that you - * passed ap_regexec(). pmatch should not be greater than the maximum number - * of subexpressions - i.e. one more than the re_nsub member of regex_t. - * - * input should be the string with the $-expressions, source should be the - * string that was matched against. - * - * It returns the substituted string, or NULL on error. - * - * Parts of this code are based on Henry Spencer's regsub(), from his - * AT&T V8 regexp package. - */ - -AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input, - const char *source, size_t nmatch, - regmatch_t pmatch[]) -{ - const char *src = input; - char *dest, *dst; - char c; - size_t no; - int len; - - if (!source) - return NULL; - if (!nmatch) - return apr_pstrdup(p, src); - - /* First pass, find the size */ - - len = 0; - - while ((c = *src++) != '\0') { - if (c == '&') - no = 0; - else if (c == '$' && apr_isdigit(*src)) - no = *src++ - '0'; - else - no = 10; - - if (no > 9) { /* Ordinary character. */ - if (c == '\\' && (*src == '$' || *src == '&')) - c = *src++; - len++; - } - else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { - len += pmatch[no].rm_eo - pmatch[no].rm_so; - } - - } - - dest = dst = apr_pcalloc(p, len + 1); - - /* Now actually fill in the string */ - - src = input; - - while ((c = *src++) != '\0') { - if (c == '&') - no = 0; - else if (c == '$' && apr_isdigit(*src)) - no = *src++ - '0'; - else - no = 10; - - if (no > 9) { /* Ordinary character. */ - if (c == '\\' && (*src == '$' || *src == '&')) - c = *src++; - *dst++ = c; - } - else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { - len = pmatch[no].rm_eo - pmatch[no].rm_so; - memcpy(dst, source + pmatch[no].rm_so, len); - dst += len; - } - - } - *dst = '\0'; - - return dest; -} - -/* - * Parse .. so we don't compromise security - */ -AP_DECLARE(void) ap_getparents(char *name) -{ - char *next; - int l, w, first_dot; - - /* Four paseses, as per RFC 1808 */ - /* a) remove ./ path segments */ - for (next = name; *next && (*next != '.'); next++) { - } - - l = w = first_dot = next - name; - while (name[l] != '\0') { - if (name[l] == '.' && IS_SLASH(name[l + 1]) - && (l == 0 || IS_SLASH(name[l - 1]))) - l += 2; - else - name[w++] = name[l++]; - } - - /* b) remove trailing . path, segment */ - if (w == 1 && name[0] == '.') - w--; - else if (w > 1 && name[w - 1] == '.' && IS_SLASH(name[w - 2])) - w--; - name[w] = '\0'; - - /* c) remove all xx/../ segments. (including leading ../ and /../) */ - l = first_dot; - - while (name[l] != '\0') { - if (name[l] == '.' && name[l + 1] == '.' && IS_SLASH(name[l + 2]) - && (l == 0 || IS_SLASH(name[l - 1]))) { - register int m = l + 3, n; - - l = l - 2; - if (l >= 0) { - while (l >= 0 && !IS_SLASH(name[l])) - l--; - l++; - } - else - l = 0; - n = l; - while ((name[n] = name[m])) - (++n, ++m); - } - else - ++l; - } - - /* d) remove trailing xx/.. segment. */ - if (l == 2 && name[0] == '.' && name[1] == '.') - name[0] = '\0'; - else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' - && IS_SLASH(name[l - 3])) { - l = l - 4; - if (l >= 0) { - while (l >= 0 && !IS_SLASH(name[l])) - l--; - l++; - } - else - l = 0; - name[l] = '\0'; - } -} - -AP_DECLARE(void) ap_no2slash(char *name) -{ - char *d, *s; - - s = d = name; - -#ifdef HAVE_UNC_PATHS - /* Check for UNC names. Leave leading two slashes. */ - if (s[0] == '/' && s[1] == '/') - *d++ = *s++; -#endif - - while (*s) { - if ((*d++ = *s) == '/') { - do { - ++s; - } while (*s == '/'); - } - else { - ++s; - } - } - *d = '\0'; -} - - -/* - * copy at most n leading directories of s into d - * d should be at least as large as s plus 1 extra byte - * assumes n > 0 - * the return value is the ever useful pointer to the trailing \0 of d - * - * MODIFIED FOR HAVE_DRIVE_LETTERS and NETWARE environments, - * so that if n == 0, "/" is returned in d with n == 1 - * and s == "e:/test.html", "e:/" is returned in d - * *** See also directory_walk in modules/http/http_request.c - - * examples: - * /a/b, 0 ==> / (true for all platforms) - * /a/b, 1 ==> / - * /a/b, 2 ==> /a/ - * /a/b, 3 ==> /a/b/ - * /a/b, 4 ==> /a/b/ - * - * c:/a/b 0 ==> / - * c:/a/b 1 ==> c:/ - * c:/a/b 2 ==> c:/a/ - * c:/a/b 3 ==> c:/a/b - * c:/a/b 4 ==> c:/a/b - */ -AP_DECLARE(char *) ap_make_dirstr_prefix(char *d, const char *s, int n) -{ - if (n < 1) { - *d = '/'; - *++d = '\0'; - return (d); - } - - for (;;) { - if (*s == '\0' || (*s == '/' && (--n) == 0)) { - *d = '/'; - break; - } - *d++ = *s++; - } - *++d = 0; - return (d); -} - - -/* - * return the parent directory name including trailing / of the file s - */ -AP_DECLARE(char *) ap_make_dirstr_parent(apr_pool_t *p, const char *s) -{ - const char *last_slash = ap_strrchr_c(s, '/'); - char *d; - int l; - - if (last_slash == NULL) { - return apr_pstrdup(p, ""); - } - l = (last_slash - s) + 1; - d = apr_palloc(p, l + 1); - memcpy(d, s, l); - d[l] = 0; - return (d); -} - - -AP_DECLARE(int) ap_count_dirs(const char *path) -{ - register int x, n; - - for (x = 0, n = 0; path[x]; x++) - if (path[x] == '/') - n++; - return n; -} - -AP_DECLARE(char *) ap_getword_nc(apr_pool_t *atrans, char **line, char stop) -{ - return ap_getword(atrans, (const char **) line, stop); -} - -AP_DECLARE(char *) ap_getword(apr_pool_t *atrans, const char **line, char stop) -{ - const char *pos = *line; - int len; - char *res; - - while ((*pos != stop) && *pos) { - ++pos; - } - - len = pos - *line; - res = (char *)apr_palloc(atrans, len + 1); - memcpy(res, *line, len); - res[len] = 0; - - if (stop) { - while (*pos == stop) { - ++pos; - } - } - *line = pos; - - return res; -} - -AP_DECLARE(char *) ap_getword_white_nc(apr_pool_t *atrans, char **line) -{ - return ap_getword_white(atrans, (const char **) line); -} - -AP_DECLARE(char *) ap_getword_white(apr_pool_t *atrans, const char **line) -{ - const char *pos = *line; - int len; - char *res; - - while (!apr_isspace(*pos) && *pos) { - ++pos; - } - - len = pos - *line; - res = (char *)apr_palloc(atrans, len + 1); - memcpy(res, *line, len); - res[len] = 0; - - while (apr_isspace(*pos)) { - ++pos; - } - - *line = pos; - - return res; -} - -AP_DECLARE(char *) ap_getword_nulls_nc(apr_pool_t *atrans, char **line, - char stop) -{ - return ap_getword_nulls(atrans, (const char **) line, stop); -} - -AP_DECLARE(char *) ap_getword_nulls(apr_pool_t *atrans, const char **line, - char stop) -{ - const char *pos = ap_strchr_c(*line, stop); - char *res; - - if (!pos) { - res = apr_pstrdup(atrans, *line); - *line += strlen(*line); - return res; - } - - res = apr_pstrndup(atrans, *line, pos - *line); - - ++pos; - - *line = pos; - - return res; -} - -/* Get a word, (new) config-file style --- quoted strings and backslashes - * all honored - */ - -static char *substring_conf(apr_pool_t *p, const char *start, int len, - char quote) -{ - char *result = apr_palloc(p, len + 2); - char *resp = result; - int i; - - for (i = 0; i < len; ++i) { - if (start[i] == '\\' && (start[i + 1] == '\\' - || (quote && start[i + 1] == quote))) - *resp++ = start[++i]; - else - *resp++ = start[i]; - } - - *resp++ = '\0'; -#if RESOLVE_ENV_PER_TOKEN - return (char *)ap_resolve_env(p,result); -#else - return result; -#endif -} - -AP_DECLARE(char *) ap_getword_conf_nc(apr_pool_t *p, char **line) -{ - return ap_getword_conf(p, (const char **) line); -} - -AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line) -{ - const char *str = *line, *strend; - char *res; - char quote; - - while (*str && apr_isspace(*str)) - ++str; - - if (!*str) { - *line = str; - return ""; - } - - if ((quote = *str) == '"' || quote == '\'') { - strend = str + 1; - while (*strend && *strend != quote) { - if (*strend == '\\' && strend[1] && strend[1] == quote) - strend += 2; - else - ++strend; - } - res = substring_conf(p, str + 1, strend - str - 1, quote); - - if (*strend == quote) - ++strend; - } - else { - strend = str; - while (*strend && !apr_isspace(*strend)) - ++strend; - - res = substring_conf(p, str, strend - str, 0); - } - - while (*strend && apr_isspace(*strend)) - ++strend; - *line = strend; - return res; -} - -/* Check a string for any ${ENV} environment variable - * construct and replace each them by the value of - * that environment variable, if it exists. If the - * environment value does not exist, leave the ${ENV} - * construct alone; it means something else. - */ -AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word) -{ -# define SMALL_EXPANSION 5 - struct sll { - struct sll *next; - const char *string; - apr_size_t len; - } *result, *current, sresult[SMALL_EXPANSION]; - char *res_buf, *cp; - const char *s, *e, *ep; - unsigned spc; - apr_size_t outlen; - - s = ap_strchr_c(word, '$'); - if (!s) { - return word; - } - - /* well, actually something to do */ - ep = word + strlen(word); - spc = 0; - result = current = &(sresult[spc++]); - current->next = NULL; - current->string = word; - current->len = s - word; - outlen = current->len; - - do { - /* prepare next entry */ - if (current->len) { - current->next = (spc < SMALL_EXPANSION) - ? &(sresult[spc++]) - : (struct sll *)apr_palloc(p, - sizeof(*current->next)); - current = current->next; - current->next = NULL; - current->len = 0; - } - - if (*s == '$') { - if (s[1] == '{' && (e = ap_strchr_c(s, '}'))) { - word = getenv(apr_pstrndup(p, s+2, e-s-2)); - if (word) { - current->string = word; - current->len = strlen(word); - outlen += current->len; - } - else { - current->string = s; - current->len = e - s + 1; - outlen += current->len; - } - s = e + 1; - } - else { - current->string = s++; - current->len = 1; - ++outlen; - } - } - else { - word = s; - s = ap_strchr_c(s, '$'); - current->string = word; - current->len = s ? s - word : ep - word; - outlen += current->len; - } - } while (s && *s); - - /* assemble result */ - res_buf = cp = apr_palloc(p, outlen + 1); - do { - if (result->len) { - memcpy(cp, result->string, result->len); - cp += result->len; - } - result = result->next; - } while (result); - res_buf[outlen] = '\0'; - - return res_buf; -} - -AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp) -{ -#ifdef DEBUG - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, - "Done with config file %s", cfp->name); -#endif - return (cfp->close == NULL) ? 0 : cfp->close(cfp->param); -} - -static apr_status_t cfg_close(void *param) -{ - apr_file_t *cfp = (apr_file_t *) param; - return (apr_file_close(cfp)); -} - -static int cfg_getch(void *param) -{ - char ch; - apr_file_t *cfp = (apr_file_t *) param; - if (apr_file_getc(&ch, cfp) == APR_SUCCESS) - return ch; - return (int)EOF; -} - -static void *cfg_getstr(void *buf, size_t bufsiz, void *param) -{ - apr_file_t *cfp = (apr_file_t *) param; - apr_status_t rv; - rv = apr_file_gets(buf, bufsiz, cfp); - if (rv == APR_SUCCESS || (APR_STATUS_IS_EOF(rv) && strcmp(buf, ""))) - return buf; - return NULL; -} - -/* Open a ap_configfile_t as FILE, return open ap_configfile_t struct pointer */ -AP_DECLARE(apr_status_t) ap_pcfg_openfile(ap_configfile_t **ret_cfg, - apr_pool_t *p, const char *name) -{ - ap_configfile_t *new_cfg; - apr_file_t *file = NULL; - apr_finfo_t finfo; - apr_status_t status; -#ifdef DEBUG - char buf[120]; -#endif - - if (name == NULL) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "Internal error: pcfg_openfile() called with NULL filename"); - return APR_EBADF; - } - - status = apr_file_open(&file, name, APR_READ | APR_BUFFERED, - APR_OS_DEFAULT, p); -#ifdef DEBUG - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, - "Opening config file %s (%s)", - name, (status != APR_SUCCESS) ? - apr_strerror(status, buf, sizeof(buf)) : "successful"); -#endif - if (status != APR_SUCCESS) - return status; - - status = apr_file_info_get(&finfo, APR_FINFO_TYPE, file); - if (status != APR_SUCCESS) - return status; - - if (finfo.filetype != APR_REG && -#if defined(WIN32) || defined(OS2) || defined(NETWARE) - strcasecmp(apr_filename_of_pathname(name), "nul") != 0) { -#else - strcmp(name, "/dev/null") != 0) { -#endif /* WIN32 || OS2 */ - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "Access to file %s denied by server: not a regular file", - name); - apr_file_close(file); - return APR_EBADF; - } - -#ifdef WIN32 - /* Some twisted character [no pun intended] at MS decided that a - * zero width joiner as the lead wide character would be ideal for - * describing Unicode text files. This was further convoluted to - * another MSism that the same character mapped into utf-8, EF BB BF - * would signify utf-8 text files. - * - * Since MS configuration files are all protecting utf-8 encoded - * Unicode path, file and resource names, we already have the correct - * WinNT encoding. But at least eat the stupid three bytes up front. - */ - { - unsigned char buf[4]; - apr_size_t len = 3; - status = apr_file_read(file, buf, &len); - if ((status != APR_SUCCESS) || (len < 3) - || memcmp(buf, "\xEF\xBB\xBF", 3) != 0) { - apr_off_t zero = 0; - apr_file_seek(file, APR_SET, &zero); - } - } -#endif - - new_cfg = apr_palloc(p, sizeof(*new_cfg)); - new_cfg->param = file; - new_cfg->name = apr_pstrdup(p, name); - new_cfg->getch = (int (*)(void *)) cfg_getch; - new_cfg->getstr = (void *(*)(void *, size_t, void *)) cfg_getstr; - new_cfg->close = (int (*)(void *)) cfg_close; - new_cfg->line_number = 0; - *ret_cfg = new_cfg; - return APR_SUCCESS; -} - - -/* Allocate a ap_configfile_t handle with user defined functions and params */ -AP_DECLARE(ap_configfile_t *) ap_pcfg_open_custom(apr_pool_t *p, - const char *descr, - void *param, - int(*getch)(void *param), - void *(*getstr) (void *buf, size_t bufsiz, void *param), - int(*close_func)(void *param)) -{ - ap_configfile_t *new_cfg = apr_palloc(p, sizeof(*new_cfg)); -#ifdef DEBUG - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, - "Opening config handler %s", descr); -#endif - new_cfg->param = param; - new_cfg->name = descr; - new_cfg->getch = getch; - new_cfg->getstr = getstr; - new_cfg->close = close_func; - new_cfg->line_number = 0; - return new_cfg; -} - -/* Read one character from a configfile_t */ -AP_DECLARE(int) ap_cfg_getc(ap_configfile_t *cfp) -{ - register int ch = cfp->getch(cfp->param); - if (ch == LF) - ++cfp->line_number; - return ch; -} - -/* Read one line from open ap_configfile_t, strip LF, increase line number */ -/* If custom handler does not define a getstr() function, read char by char */ -AP_DECLARE(int) ap_cfg_getline(char *buf, size_t bufsize, ap_configfile_t *cfp) -{ - /* If a "get string" function is defined, use it */ - if (cfp->getstr != NULL) { - char *src, *dst; - char *cp; - char *cbuf = buf; - size_t cbufsize = bufsize; - - while (1) { - ++cfp->line_number; - if (cfp->getstr(cbuf, cbufsize, cfp->param) == NULL) - return 1; - - /* - * check for line continuation, - * i.e. match [^\\]\\[\r]\n only - */ - cp = cbuf; - while (cp < cbuf+cbufsize && *cp != '\0') - cp++; - if (cp > cbuf && cp[-1] == LF) { - cp--; - if (cp > cbuf && cp[-1] == CR) - cp--; - if (cp > cbuf && cp[-1] == '\\') { - cp--; - if (!(cp > cbuf && cp[-1] == '\\')) { - /* - * line continuation requested - - * then remove backslash and continue - */ - cbufsize -= (cp-cbuf); - cbuf = cp; - continue; - } - else { - /* - * no real continuation because escaped - - * then just remove escape character - */ - for ( ; cp < cbuf+cbufsize && *cp != '\0'; cp++) - cp[0] = cp[1]; - } - } - } - break; - } - - /* - * Leading and trailing white space is eliminated completely - */ - src = buf; - while (apr_isspace(*src)) - ++src; - /* blast trailing whitespace */ - dst = &src[strlen(src)]; - while (--dst >= src && apr_isspace(*dst)) - *dst = '\0'; - /* Zap leading whitespace by shifting */ - if (src != buf) - for (dst = buf; (*dst++ = *src++) != '\0'; ) - ; - -#ifdef DEBUG_CFG_LINES - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "Read config: %s", buf); -#endif - return 0; - } else { - /* No "get string" function defined; read character by character */ - register int c; - register size_t i = 0; - - buf[0] = '\0'; - /* skip leading whitespace */ - do { - c = cfp->getch(cfp->param); - } while (c == '\t' || c == ' '); - - if (c == EOF) - return 1; - - if(bufsize < 2) { - /* too small, assume caller is crazy */ - return 1; - } - - while (1) { - if ((c == '\t') || (c == ' ')) { - buf[i++] = ' '; - while ((c == '\t') || (c == ' ')) - c = cfp->getch(cfp->param); - } - if (c == CR) { - /* silently ignore CR (_assume_ that a LF follows) */ - c = cfp->getch(cfp->param); - } - if (c == LF) { - /* increase line number and return on LF */ - ++cfp->line_number; - } - if (c == EOF || c == 0x4 || c == LF || i >= (bufsize - 2)) { - /* - * check for line continuation - */ - if (i > 0 && buf[i-1] == '\\') { - i--; - if (!(i > 0 && buf[i-1] == '\\')) { - /* line is continued */ - c = cfp->getch(cfp->param); - continue; - } - /* else nothing needs be done because - * then the backslash is escaped and - * we just strip to a single one - */ - } - /* blast trailing whitespace */ - while (i > 0 && apr_isspace(buf[i - 1])) - --i; - buf[i] = '\0'; -#ifdef DEBUG_CFG_LINES - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, - "Read config: %s", buf); -#endif - return 0; - } - buf[i] = c; - ++i; - c = cfp->getch(cfp->param); - } - } -} - -/* Size an HTTP header field list item, as separated by a comma. - * The return value is a pointer to the beginning of the non-empty list item - * within the original string (or NULL if there is none) and the address - * of field is shifted to the next non-comma, non-whitespace character. - * len is the length of the item excluding any beginning whitespace. - */ -AP_DECLARE(const char *) ap_size_list_item(const char **field, int *len) -{ - const unsigned char *ptr = (const unsigned char *)*field; - const unsigned char *token; - int in_qpair, in_qstr, in_com; - - /* Find first non-comma, non-whitespace byte */ - - while (*ptr == ',' || apr_isspace(*ptr)) - ++ptr; - - token = ptr; - - /* Find the end of this item, skipping over dead bits */ - - for (in_qpair = in_qstr = in_com = 0; - *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); - ++ptr) { - - if (in_qpair) { - in_qpair = 0; - } - else { - switch (*ptr) { - case '\\': in_qpair = 1; /* quoted-pair */ - break; - case '"' : if (!in_com) /* quoted string delim */ - in_qstr = !in_qstr; - break; - case '(' : if (!in_qstr) /* comment (may nest) */ - ++in_com; - break; - case ')' : if (in_com) /* end comment */ - --in_com; - break; - default : break; - } - } - } - - if ((*len = (ptr - token)) == 0) { - *field = (const char *)ptr; - return NULL; - } - - /* Advance field pointer to the next non-comma, non-white byte */ - - while (*ptr == ',' || apr_isspace(*ptr)) - ++ptr; - - *field = (const char *)ptr; - return (const char *)token; -} - -/* Retrieve an HTTP header field list item, as separated by a comma, - * while stripping insignificant whitespace and lowercasing anything not in - * a quoted string or comment. The return value is a new string containing - * the converted list item (or NULL if none) and the address pointed to by - * field is shifted to the next non-comma, non-whitespace. - */ -AP_DECLARE(char *) ap_get_list_item(apr_pool_t *p, const char **field) -{ - const char *tok_start; - const unsigned char *ptr; - unsigned char *pos; - char *token; - int addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0, tok_len = 0; - - /* Find the beginning and maximum length of the list item so that - * we can allocate a buffer for the new string and reset the field. - */ - if ((tok_start = ap_size_list_item(field, &tok_len)) == NULL) { - return NULL; - } - token = apr_palloc(p, tok_len + 1); - - /* Scan the token again, but this time copy only the good bytes. - * We skip extra whitespace and any whitespace around a '=', '/', - * or ';' and lowercase normal characters not within a comment, - * quoted-string or quoted-pair. - */ - for (ptr = (const unsigned char *)tok_start, pos = (unsigned char *)token; - *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); - ++ptr) { - - if (in_qpair) { - in_qpair = 0; - *pos++ = *ptr; - } - else { - switch (*ptr) { - case '\\': in_qpair = 1; - if (addspace == 1) - *pos++ = ' '; - *pos++ = *ptr; - addspace = 0; - break; - case '"' : if (!in_com) - in_qstr = !in_qstr; - if (addspace == 1) - *pos++ = ' '; - *pos++ = *ptr; - addspace = 0; - break; - case '(' : if (!in_qstr) - ++in_com; - if (addspace == 1) - *pos++ = ' '; - *pos++ = *ptr; - addspace = 0; - break; - case ')' : if (in_com) - --in_com; - *pos++ = *ptr; - addspace = 0; - break; - case ' ' : - case '\t': if (addspace) - break; - if (in_com || in_qstr) - *pos++ = *ptr; - else - addspace = 1; - break; - case '=' : - case '/' : - case ';' : if (!(in_com || in_qstr)) - addspace = -1; - *pos++ = *ptr; - break; - default : if (addspace == 1) - *pos++ = ' '; - *pos++ = (in_com || in_qstr) ? *ptr - : apr_tolower(*ptr); - addspace = 0; - break; - } - } - } - *pos = '\0'; - - return token; -} - -/* Find an item in canonical form (lowercase, no extra spaces) within - * an HTTP field value list. Returns 1 if found, 0 if not found. - * This would be much more efficient if we stored header fields as - * an array of list items as they are received instead of a plain string. - */ -AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line, - const char *tok) -{ - const unsigned char *pos; - const unsigned char *ptr = (const unsigned char *)line; - int good = 0, addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0; - - if (!line || !tok) - return 0; - - do { /* loop for each item in line's list */ - - /* Find first non-comma, non-whitespace byte */ - - while (*ptr == ',' || apr_isspace(*ptr)) - ++ptr; - - if (*ptr) - good = 1; /* until proven otherwise for this item */ - else - break; /* no items left and nothing good found */ - - /* We skip extra whitespace and any whitespace around a '=', '/', - * or ';' and lowercase normal characters not within a comment, - * quoted-string or quoted-pair. - */ - for (pos = (const unsigned char *)tok; - *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); - ++ptr) { - - if (in_qpair) { - in_qpair = 0; - if (good) - good = (*pos++ == *ptr); - } - else { - switch (*ptr) { - case '\\': in_qpair = 1; - if (addspace == 1) - good = good && (*pos++ == ' '); - good = good && (*pos++ == *ptr); - addspace = 0; - break; - case '"' : if (!in_com) - in_qstr = !in_qstr; - if (addspace == 1) - good = good && (*pos++ == ' '); - good = good && (*pos++ == *ptr); - addspace = 0; - break; - case '(' : if (!in_qstr) - ++in_com; - if (addspace == 1) - good = good && (*pos++ == ' '); - good = good && (*pos++ == *ptr); - addspace = 0; - break; - case ')' : if (in_com) - --in_com; - good = good && (*pos++ == *ptr); - addspace = 0; - break; - case ' ' : - case '\t': if (addspace || !good) - break; - if (in_com || in_qstr) - good = (*pos++ == *ptr); - else - addspace = 1; - break; - case '=' : - case '/' : - case ';' : if (!(in_com || in_qstr)) - addspace = -1; - good = good && (*pos++ == *ptr); - break; - default : if (!good) - break; - if (addspace == 1) - good = (*pos++ == ' '); - if (in_com || in_qstr) - good = good && (*pos++ == *ptr); - else - good = good && (*pos++ == apr_tolower(*ptr)); - addspace = 0; - break; - } - } - } - if (good && *pos) - good = 0; /* not good if only a prefix was matched */ - - } while (*ptr && !good); - - return good; -} - - -/* Retrieve a token, spacing over it and returning a pointer to - * the first non-white byte afterwards. Note that these tokens - * are delimited by semis and commas; and can also be delimited - * by whitespace at the caller's option. - */ - -AP_DECLARE(char *) ap_get_token(apr_pool_t *p, const char **accept_line, - int accept_white) -{ - const char *ptr = *accept_line; - const char *tok_start; - char *token; - int tok_len; - - /* Find first non-white byte */ - - while (*ptr && apr_isspace(*ptr)) - ++ptr; - - tok_start = ptr; - - /* find token end, skipping over quoted strings. - * (comments are already gone). - */ - - while (*ptr && (accept_white || !apr_isspace(*ptr)) - && *ptr != ';' && *ptr != ',') { - if (*ptr++ == '"') - while (*ptr) - if (*ptr++ == '"') - break; - } - - tok_len = ptr - tok_start; - token = apr_pstrndup(p, tok_start, tok_len); - - /* Advance accept_line pointer to the next non-white byte */ - - while (*ptr && apr_isspace(*ptr)) - ++ptr; - - *accept_line = ptr; - return token; -} - - -/* find http tokens, see the definition of token from RFC2068 */ -AP_DECLARE(int) ap_find_token(apr_pool_t *p, const char *line, const char *tok) -{ - const unsigned char *start_token; - const unsigned char *s; - - if (!line) - return 0; - - s = (const unsigned char *)line; - for (;;) { - /* find start of token, skip all stop characters, note NUL - * isn't a token stop, so we don't need to test for it - */ - while (TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { - ++s; - } - if (!*s) { - return 0; - } - start_token = s; - /* find end of the token */ - while (*s && !TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { - ++s; - } - if (!strncasecmp((const char *)start_token, (const char *)tok, - s - start_token)) { - return 1; - } - if (!*s) { - return 0; - } - } -} - - -AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line, - const char *tok) -{ - int llen, tlen, lidx; - - if (!line) - return 0; - - llen = strlen(line); - tlen = strlen(tok); - lidx = llen - tlen; - - if (lidx < 0 || - (lidx > 0 && !(apr_isspace(line[lidx - 1]) || line[lidx - 1] == ','))) - return 0; - - return (strncasecmp(&line[lidx], tok, tlen) == 0); -} - -AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *str) -{ - char *cmd; - unsigned char *d; - const unsigned char *s; - - cmd = apr_palloc(p, 2 * strlen(str) + 1); /* Be safe */ - d = (unsigned char *)cmd; - s = (const unsigned char *)str; - for (; *s; ++s) { - -#if defined(OS2) || defined(WIN32) - /* - * Newlines to Win32/OS2 CreateProcess() are ill advised. - * Convert them to spaces since they are effectively white - * space to most applications - */ - if (*s == '\r' || *s == '\n') { - *d++ = ' '; - continue; - } -#endif - - if (TEST_CHAR(*s, T_ESCAPE_SHELL_CMD)) { - *d++ = '\\'; - } - *d++ = *s; - } - *d = '\0'; - - return cmd; -} - -static char x2c(const char *what) -{ - register char digit; - -#if !APR_CHARSET_EBCDIC - digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 - : (what[0] - '0')); - digit *= 16; - digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 - : (what[1] - '0')); -#else /*APR_CHARSET_EBCDIC*/ - char xstr[5]; - xstr[0]='0'; - xstr[1]='x'; - xstr[2]=what[0]; - xstr[3]=what[1]; - xstr[4]='\0'; - digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, - 0xFF & strtol(xstr, NULL, 16)); -#endif /*APR_CHARSET_EBCDIC*/ - return (digit); -} - -/* - * Unescapes a URL. - * Returns 0 on success, non-zero on error - * Failure is due to - * bad % escape returns HTTP_BAD_REQUEST - * - * decoding %00 -> \0 (the null character) - * decoding %2f -> / (a special character) - * returns HTTP_NOT_FOUND - */ -AP_DECLARE(int) ap_unescape_url(char *url) -{ - register int badesc, badpath; - char *x, *y; - - badesc = 0; - badpath = 0; - /* Initial scan for first '%'. Don't bother writing values before - * seeing a '%' */ - y = strchr(url, '%'); - if (y == NULL) { - return OK; - } - for (x = y; *y; ++x, ++y) { - if (*y != '%') - *x = *y; - else { - if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { - badesc = 1; - *x = '%'; - } - else { - *x = x2c(y + 1); - y += 2; - if (IS_SLASH(*x) || *x == '\0') - badpath = 1; - } - } - } - *x = '\0'; - if (badesc) - return HTTP_BAD_REQUEST; - else if (badpath) - return HTTP_NOT_FOUND; - else - return OK; -} - -AP_DECLARE(int) ap_unescape_url_keep2f(char *url) -{ - register int badesc, badpath; - char *x, *y; - - badesc = 0; - badpath = 0; - /* Initial scan for first '%'. Don't bother writing values before - * seeing a '%' */ - y = strchr(url, '%'); - if (y == NULL) { - return OK; - } - for (x = y; *y; ++x, ++y) { - if (*y != '%') { - *x = *y; - } - else { - if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { - badesc = 1; - *x = '%'; - } - else { - char decoded; - decoded = x2c(y + 1); - if (decoded == '\0') { - badpath = 1; - } - else { - *x = decoded; - y += 2; - } - } - } - } - *x = '\0'; - if (badesc) { - return HTTP_BAD_REQUEST; - } - else if (badpath) { - return HTTP_NOT_FOUND; - } - else { - return OK; - } -} - -AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname, - apr_port_t port, const request_rec *r) -{ - if (ap_is_default_port(port, r)) { - return apr_pstrdup(p, hostname); - } - else { - return apr_psprintf(p, "%s:%u", hostname, port); - } -} - -/* c2x takes an unsigned, and expects the caller has guaranteed that - * 0 <= what < 256... which usually means that you have to cast to - * unsigned char first, because (unsigned)(char)(x) first goes through - * signed extension to an int before the unsigned cast. - * - * The reason for this assumption is to assist gcc code generation -- - * the unsigned char -> unsigned extension is already done earlier in - * both uses of this code, so there's no need to waste time doing it - * again. - */ -static const char c2x_table[] = "0123456789abcdef"; - -static APR_INLINE unsigned char *c2x(unsigned what, unsigned char *where) -{ -#if APR_CHARSET_EBCDIC - what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what); -#endif /*APR_CHARSET_EBCDIC*/ - *where++ = '%'; - *where++ = c2x_table[what >> 4]; - *where++ = c2x_table[what & 0xf]; - return where; -} - -/* - * escape_path_segment() escapes a path segment, as defined in RFC 1808. This - * routine is (should be) OS independent. - * - * os_escape_path() converts an OS path to a URL, in an OS dependent way. In all - * cases if a ':' occurs before the first '/' in the URL, the URL should be - * prefixed with "./" (or the ':' escaped). In the case of Unix, this means - * leaving '/' alone, but otherwise doing what escape_path_segment() does. For - * efficiency reasons, we don't use escape_path_segment(), which is provided for - * reference. Again, RFC 1808 is where this stuff is defined. - * - * If partial is set, os_escape_path() assumes that the path will be appended to - * something with a '/' in it (and thus does not prefix "./"). - */ - -AP_DECLARE(char *) ap_escape_path_segment(apr_pool_t *p, const char *segment) -{ - char *copy = apr_palloc(p, 3 * strlen(segment) + 1); - const unsigned char *s = (const unsigned char *)segment; - unsigned char *d = (unsigned char *)copy; - unsigned c; - - while ((c = *s)) { - if (TEST_CHAR(c, T_ESCAPE_PATH_SEGMENT)) { - d = c2x(c, d); - } - else { - *d++ = c; - } - ++s; - } - *d = '\0'; - return copy; -} - -AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partial) -{ - char *copy = apr_palloc(p, 3 * strlen(path) + 3); - const unsigned char *s = (const unsigned char *)path; - unsigned char *d = (unsigned char *)copy; - unsigned c; - - if (!partial) { - const char *colon = ap_strchr_c(path, ':'); - const char *slash = ap_strchr_c(path, '/'); - - if (colon && (!slash || colon < slash)) { - *d++ = '.'; - *d++ = '/'; - } - } - while ((c = *s)) { - if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) { - d = c2x(c, d); - } - else { - *d++ = c; - } - ++s; - } - *d = '\0'; - return copy; -} - -/* ap_escape_uri is now a macro for os_escape_path */ - -AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s) -{ - int i, j; - char *x; - - /* first, count the number of extra characters */ - for (i = 0, j = 0; s[i] != '\0'; i++) - if (s[i] == '<' || s[i] == '>') - j += 3; - else if (s[i] == '&') - j += 4; - else if (s[i] == '"') - j += 5; - - if (j == 0) - return apr_pstrmemdup(p, s, i); - - x = apr_palloc(p, i + j + 1); - for (i = 0, j = 0; s[i] != '\0'; i++, j++) - if (s[i] == '<') { - memcpy(&x[j], "<", 4); - j += 3; - } - else if (s[i] == '>') { - memcpy(&x[j], ">", 4); - j += 3; - } - else if (s[i] == '&') { - memcpy(&x[j], "&", 5); - j += 4; - } - else if (s[i] == '"') { - memcpy(&x[j], """, 6); - j += 5; - } - else - x[j] = s[i]; - - x[j] = '\0'; - return x; -} - -AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str) -{ - char *ret; - unsigned char *d; - const unsigned char *s; - - if (!str) { - return NULL; - } - - ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */ - d = (unsigned char *)ret; - s = (const unsigned char *)str; - for (; *s; ++s) { - - if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) { - *d++ = '\\'; - switch(*s) { - case '\b': - *d++ = 'b'; - break; - case '\n': - *d++ = 'n'; - break; - case '\r': - *d++ = 'r'; - break; - case '\t': - *d++ = 't'; - break; - case '\v': - *d++ = 'v'; - break; - case '\\': - case '"': - *d++ = *s; - break; - default: - c2x(*s, d); - *d = 'x'; - d += 3; - } - } - else { - *d++ = *s; - } - } - *d = '\0'; - - return ret; -} - -AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source, - apr_size_t buflen) -{ - unsigned char *d, *ep; - const unsigned char *s; - - if (!source || !buflen) { /* be safe */ - return 0; - } - - d = (unsigned char *)dest; - s = (const unsigned char *)source; - ep = d + buflen - 1; - - for (; d < ep && *s; ++s) { - - if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) { - *d++ = '\\'; - if (d >= ep) { - --d; - break; - } - - switch(*s) { - case '\b': - *d++ = 'b'; - break; - case '\n': - *d++ = 'n'; - break; - case '\r': - *d++ = 'r'; - break; - case '\t': - *d++ = 't'; - break; - case '\v': - *d++ = 'v'; - break; - case '\\': - *d++ = *s; - break; - case '"': /* no need for this in error log */ - d[-1] = *s; - break; - default: - if (d >= ep - 2) { - ep = --d; /* break the for loop as well */ - break; - } - c2x(*s, d); - *d = 'x'; - d += 3; - } - } - else { - *d++ = *s; - } - } - *d = '\0'; - - return (d - (unsigned char *)dest); -} - -AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path) -{ - apr_finfo_t finfo; - - if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) - return 0; /* in error condition, just return no */ - - return (finfo.filetype == APR_DIR); -} - -AP_DECLARE(int) ap_is_rdirectory(apr_pool_t *p, const char *path) -{ - apr_finfo_t finfo; - - if (apr_lstat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) - return 0; /* in error condition, just return no */ - - return (finfo.filetype == APR_DIR); -} - -AP_DECLARE(char *) ap_make_full_path(apr_pool_t *a, const char *src1, - const char *src2) -{ - apr_size_t len1, len2; - char *path; - - len1 = strlen(src1); - len2 = strlen(src2); - /* allocate +3 for '/' delimiter, trailing NULL and overallocate - * one extra byte to allow the caller to add a trailing '/' - */ - path = (char *)apr_palloc(a, len1 + len2 + 3); - if (len1 == 0) { - *path = '/'; - memcpy(path + 1, src2, len2 + 1); - } - else { - char *next; - memcpy(path, src1, len1); - next = path + len1; - if (next[-1] != '/') { - *next++ = '/'; - } - memcpy(next, src2, len2 + 1); - } - return path; -} - -/* - * Check for an absoluteURI syntax (see section 3.2 in RFC2068). - */ -AP_DECLARE(int) ap_is_url(const char *u) -{ - register int x; - - for (x = 0; u[x] != ':'; x++) { - if ((!u[x]) || - ((!apr_isalpha(u[x])) && (!apr_isdigit(u[x])) && - (u[x] != '+') && (u[x] != '-') && (u[x] != '.'))) { - return 0; - } - } - - return (x ? 1 : 0); /* If the first character is ':', it's broken, too */ -} - -AP_DECLARE(int) ap_ind(const char *s, char c) -{ - const char *p = ap_strchr_c(s, c); - - if (p == NULL) - return -1; - return p - s; -} - -AP_DECLARE(int) ap_rind(const char *s, char c) -{ - const char *p = ap_strrchr_c(s, c); - - if (p == NULL) - return -1; - return p - s; -} - -AP_DECLARE(void) ap_str_tolower(char *str) -{ - while (*str) { - *str = apr_tolower(*str); - ++str; - } -} - -static char *find_fqdn(apr_pool_t *a, struct hostent *p) -{ - int x; - - if (!strchr(p->h_name, '.')) { - if (p->h_aliases) { - for (x = 0; p->h_aliases[x]; ++x) { - if (strchr(p->h_aliases[x], '.') && - (!strncasecmp(p->h_aliases[x], p->h_name, - strlen(p->h_name)))) - return apr_pstrdup(a, p->h_aliases[x]); - } - } - return NULL; - } - return apr_pstrdup(a, (void *) p->h_name); -} - -char *ap_get_local_host(apr_pool_t *a) -{ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - char str[MAXHOSTNAMELEN + 1]; - char *server_hostname = NULL; - struct hostent *p; - -#ifdef BEOS_R5 - if (gethostname(str, sizeof(str) - 1) == 0) -#else - if (gethostname(str, sizeof(str) - 1) != 0) -#endif - { - ap_log_perror(APLOG_MARK, APLOG_STARTUP | APLOG_WARNING, 0, a, - "%s: gethostname() failed to determine ServerName", - ap_server_argv0); - } - else - { - str[sizeof(str) - 1] = '\0'; - /* TODO: Screaming for APR-ization */ - if ((!(p = gethostbyname(str))) - || (!(server_hostname = find_fqdn(a, p)))) { - /* Recovery - return the default servername by IP: */ - if (p && p->h_addr_list[0]) { - apr_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]); - server_hostname = apr_pstrdup(a, str); - /* We will drop through to report the IP-named server */ - } - } - else { - /* Since we found a fdqn, return it with no logged message. */ - return server_hostname; - } - } - - if (!server_hostname) - server_hostname = apr_pstrdup(a, "127.0.0.1"); - - ap_log_perror(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, a, - "%s: Could not determine the server's fully qualified " - "domain name, using %s for ServerName", - ap_server_argv0, server_hostname); - - return server_hostname; -} - -/* simple 'pool' alloc()ing glue to apr_base64.c - */ -AP_DECLARE(char *) ap_pbase64decode(apr_pool_t *p, const char *bufcoded) -{ - char *decoded; - int l; - - decoded = (char *) apr_palloc(p, 1 + apr_base64_decode_len(bufcoded)); - l = apr_base64_decode(decoded, bufcoded); - decoded[l] = '\0'; /* make binary sequence into string */ - - return decoded; -} - -AP_DECLARE(char *) ap_pbase64encode(apr_pool_t *p, char *string) -{ - char *encoded; - int l = strlen(string); - - encoded = (char *) apr_palloc(p, 1 + apr_base64_encode_len(l)); - l = apr_base64_encode(encoded, string, l); - encoded[l] = '\0'; /* make binary sequence into string */ - - return encoded; -} - -/* we want to downcase the type/subtype for comparison purposes - * but nothing else because ;parameter=foo values are case sensitive. - * XXX: in truth we want to downcase parameter names... but really, - * apache has never handled parameters and such correctly. You - * also need to compress spaces and such to be able to compare - * properly. -djg - */ -AP_DECLARE(void) ap_content_type_tolower(char *str) -{ - char *semi; - - semi = strchr(str, ';'); - if (semi) { - *semi = '\0'; - } - while (*str) { - *str = apr_tolower(*str); - ++str; - } - if (semi) { - *semi = ';'; - } -} - -/* - * Given a string, replace any bare " with \" . - */ -AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring) -{ - int newlen = 0; - const char *inchr = instring; - char *outchr, *outstring; - - /* - * Look through the input string, jogging the length of the output - * string up by an extra byte each time we find an unescaped ". - */ - while (*inchr != '\0') { - newlen++; - if (*inchr == '"') { - newlen++; - } - /* - * If we find a slosh, and it's not the last byte in the string, - * it's escaping something - advance past both bytes. - */ - if ((*inchr == '\\') && (inchr[1] != '\0')) { - inchr++; - newlen++; - } - inchr++; - } - outstring = apr_palloc(p, newlen + 1); - inchr = instring; - outchr = outstring; - /* - * Now copy the input string to the output string, inserting a slosh - * in front of every " that doesn't already have one. - */ - while (*inchr != '\0') { - if ((*inchr == '\\') && (inchr[1] != '\0')) { - *outchr++ = *inchr++; - *outchr++ = *inchr++; - } - if (*inchr == '"') { - *outchr++ = '\\'; - } - if (*inchr != '\0') { - *outchr++ = *inchr++; - } - } - *outchr = '\0'; - return outstring; -} diff --git a/rubbos/app/httpd-2.0.64/server/util.lo b/rubbos/app/httpd-2.0.64/server/util.lo deleted file mode 100644 index e41a8081..00000000 --- a/rubbos/app/httpd-2.0.64/server/util.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util.o' - -# Name of the non-PIC object. -non_pic_object='util.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util.o b/rubbos/app/httpd-2.0.64/server/util.o Binary files differdeleted file mode 100644 index c297bbc1..00000000 --- a/rubbos/app/httpd-2.0.64/server/util.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_cfgtree.c b/rubbos/app/httpd-2.0.64/server/util_cfgtree.c deleted file mode 100644 index 2eaae9be..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_cfgtree.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define CORE_PRIVATE -#include "util_cfgtree.h" -#include <stdlib.h> - -ap_directive_t *ap_add_node(ap_directive_t **parent, ap_directive_t *current, - ap_directive_t *toadd, int child) -{ - if (current == NULL) { - /* we just started a new parent */ - if (*parent != NULL) { - (*parent)->first_child = toadd; - toadd->parent = *parent; - } - if (child) { - /* First item in config file or container is a container */ - *parent = toadd; - return NULL; - } - return toadd; - } - current->next = toadd; - toadd->parent = *parent; - if (child) { - /* switch parents, navigate into child */ - *parent = toadd; - return NULL; - } - return toadd; -} - - diff --git a/rubbos/app/httpd-2.0.64/server/util_cfgtree.lo b/rubbos/app/httpd-2.0.64/server/util_cfgtree.lo deleted file mode 100644 index 60941280..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_cfgtree.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_cfgtree.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_cfgtree.o' - -# Name of the non-PIC object. -non_pic_object='util_cfgtree.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_cfgtree.o b/rubbos/app/httpd-2.0.64/server/util_cfgtree.o Binary files differdeleted file mode 100644 index 55b3915f..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_cfgtree.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_charset.c b/rubbos/app/httpd-2.0.64/server/util_charset.c deleted file mode 100644 index c21cf103..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_charset.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ap_config.h" - -#ifdef APACHE_XLATE - -#include "httpd.h" -#include "http_log.h" -#include "http_core.h" -#include "util_charset.h" - -/* ap_hdrs_to_ascii, ap_hdrs_from_ascii - * - * These are the translation handles used to translate between the network - * format of protocol headers and the local machine format. - * - * For an EBCDIC machine, these are valid handles which are set up at - * initialization to translate between ISO-8859-1 and the code page of - * the source code. - * - * For an ASCII machine, these remain NULL so that when they are stored - * in the BUFF via ap_bsetop(BO_RXLATE) it ensures that no translation is - * performed. - */ - -apr_xlate_t *ap_hdrs_to_ascii, *ap_hdrs_from_ascii; - -/* ap_locale_to_ascii, ap_locale_from_ascii - * - * These handles are used for the translation of content, unless a - * configuration module overrides them. - * - * For an EBCDIC machine, these are valid handles which are set up at - * initialization to translate between ISO-8859-1 and the code page of - * the httpd process's locale. - * - * For an ASCII machine, these remain NULL so that no translation is - * performed (unless a configuration module does something, of course). - */ - -apr_xlate_t *ap_locale_to_ascii, *ap_locale_from_ascii; - -#endif /*APACHE_XLATE*/ diff --git a/rubbos/app/httpd-2.0.64/server/util_charset.lo b/rubbos/app/httpd-2.0.64/server/util_charset.lo deleted file mode 100644 index 5b1fe5c5..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_charset.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_charset.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_charset.o' - -# Name of the non-PIC object. -non_pic_object='util_charset.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_charset.o b/rubbos/app/httpd-2.0.64/server/util_charset.o Binary files differdeleted file mode 100644 index fbf7c134..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_charset.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_debug.c b/rubbos/app/httpd-2.0.64/server/util_debug.c deleted file mode 100644 index 0fefc5c8..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_debug.c +++ /dev/null @@ -1,128 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "httpd.h" -#include "http_config.h" - -/* Possibly get rid of the macros we defined in httpd.h */ -#if defined(strchr) -#undef strchr -#endif - -#if defined (strrchr) -#undef strrchr -#endif - -#if defined (strstr) -#undef strstr -#endif - - -#if defined(ap_strchr) -#undef ap_strchr -AP_DECLARE(char *) ap_strchr(char *s, int c); -#endif - -AP_DECLARE(char *) ap_strchr(char *s, int c) -{ - return strchr(s,c); -} - -#if defined(ap_strchr_c) -#undef ap_strchr_c -AP_DECLARE(const char *) ap_strchr_c(const char *s, int c); -#endif - -AP_DECLARE(const char *) ap_strchr_c(const char *s, int c) -{ - return strchr(s,c); -} - -#if defined(ap_strrchr) -#undef ap_strrchr -AP_DECLARE(char *) ap_strrchr(char *s, int c); -#endif - -AP_DECLARE(char *) ap_strrchr(char *s, int c) -{ - return strrchr(s,c); -} - -#if defined(ap_strrchr_c) -#undef ap_strrchr_c -AP_DECLARE(const char *) ap_strrchr_c(const char *s, int c); -#endif - -AP_DECLARE(const char *) ap_strrchr_c(const char *s, int c) -{ - return strrchr(s,c); -} - -#if defined(ap_strstr) -#undef ap_strstr -AP_DECLARE(char *) ap_strstr(char *s, const char *c); -#endif - -AP_DECLARE(char *) ap_strstr(char *s, const char *c) -{ - return strstr(s,c); -} - -#if defined(ap_strstr_c) -#undef ap_strstr_c -AP_DECLARE(const char *) ap_strstr_c(const char *s, const char *c); -#endif - -AP_DECLARE(const char *) ap_strstr_c(const char *s, const char *c) -{ - return strstr(s,c); -} - -#if defined(ap_get_module_config) -#undef ap_get_module_config -AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv, - const module *m); -#endif - -AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv, - const module *m) -{ - return ((void **)cv)[m->module_index]; -} - -/** - * Generic accessors for other modules to set at their own module-specific - * data - * @param conf_vector The vector in which the modules configuration is stored. - * usually r->per_dir_config or s->module_config - * @param m The module to set the data for. - * @param val The module-specific data to set - * @deffunc void ap_set_module_config(ap_conf_vector_t *cv, const module *m, void *val) - */ -#if defined(ap_set_module_config) -#undef ap_set_module_config -AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m, - void *val); -#endif - -AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m, - void *val) -{ - ((void **)cv)[m->module_index] = val; -} diff --git a/rubbos/app/httpd-2.0.64/server/util_debug.lo b/rubbos/app/httpd-2.0.64/server/util_debug.lo deleted file mode 100644 index c03cc150..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_debug.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_debug.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_debug.o' - -# Name of the non-PIC object. -non_pic_object='util_debug.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_debug.o b/rubbos/app/httpd-2.0.64/server/util_debug.o Binary files differdeleted file mode 100644 index feea30b4..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_debug.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_ebcdic.c b/rubbos/app/httpd-2.0.64/server/util_ebcdic.c deleted file mode 100644 index 458ca8f9..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_ebcdic.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ap_config.h" - -#if APR_CHARSET_EBCDIC - -#include "apr_strings.h" -#include "httpd.h" -#include "http_log.h" -#include "http_core.h" -#include "util_ebcdic.h" - -apr_status_t ap_init_ebcdic(apr_pool_t *pool) -{ - apr_status_t rv; - char buf[80]; - - rv = apr_xlate_open(&ap_hdrs_to_ascii, "ISO8859-1", APR_DEFAULT_CHARSET, pool); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_xlate_open() failed"); - return rv; - } - - rv = apr_xlate_open(&ap_hdrs_from_ascii, APR_DEFAULT_CHARSET, "ISO8859-1", pool); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_xlate_open() failed"); - return rv; - } - - rv = apr_xlate_open(&ap_locale_to_ascii, "ISO8859-1", APR_LOCALE_CHARSET, pool); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_xlate_open() failed"); - return rv; - } - - rv = apr_xlate_open(&ap_locale_from_ascii, APR_LOCALE_CHARSET, "ISO8859-1", pool); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_xlate_open() failed"); - return rv; - } - - rv = apr_MD5InitEBCDIC(ap_hdrs_to_ascii); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_MD5InitEBCDIC() failed"); - return rv; - } - - rv = apr_base64init_ebcdic(ap_hdrs_to_ascii, ap_hdrs_from_ascii); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_base64init_ebcdic() failed"); - return rv; - } - - rv = apr_SHA1InitEBCDIC(ap_hdrs_to_ascii); - if (rv) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "apr_SHA1InitEBCDIC() failed"); - return rv; - } - - return APR_SUCCESS; -} - -void ap_xlate_proto_to_ascii(char *buffer, apr_size_t len) -{ - apr_size_t inbytes_left, outbytes_left; - - inbytes_left = outbytes_left = len; - apr_xlate_conv_buffer(ap_hdrs_to_ascii, buffer, &inbytes_left, - buffer, &outbytes_left); -} - -void ap_xlate_proto_from_ascii(char *buffer, apr_size_t len) -{ - apr_size_t inbytes_left, outbytes_left; - - inbytes_left = outbytes_left = len; - apr_xlate_conv_buffer(ap_hdrs_from_ascii, buffer, &inbytes_left, - buffer, &outbytes_left); -} - -int ap_rvputs_proto_in_ascii(request_rec *r, ...) -{ - va_list va; - const char *s; - char *ascii_s; - apr_size_t len; - apr_size_t written = 0; - - va_start(va, r); - while (1) { - s = va_arg(va, const char *); - if (s == NULL) - break; - len = strlen(s); - ascii_s = apr_pstrndup(r->pool, s, len); - ap_xlate_proto_to_ascii(ascii_s, len); - if (ap_rputs(ascii_s, r) < 0) - return -1; - written += len; - } - va_end(va); - - return written; -} -#endif /* APR_CHARSET_EBCDIC */ diff --git a/rubbos/app/httpd-2.0.64/server/util_ebcdic.lo b/rubbos/app/httpd-2.0.64/server/util_ebcdic.lo deleted file mode 100644 index dc0f4e12..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_ebcdic.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_ebcdic.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_ebcdic.o' - -# Name of the non-PIC object. -non_pic_object='util_ebcdic.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_ebcdic.o b/rubbos/app/httpd-2.0.64/server/util_ebcdic.o Binary files differdeleted file mode 100644 index 0b072231..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_ebcdic.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_filter.c b/rubbos/app/httpd-2.0.64/server/util_filter.c deleted file mode 100644 index d25ec6c5..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_filter.c +++ /dev/null @@ -1,601 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define APR_WANT_STRFUNC -#include "apr_want.h" -#include "apr_lib.h" -#include "apr_hash.h" -#include "apr_strings.h" - -#include "httpd.h" -#include "http_log.h" -#include "util_filter.h" - -/* NOTE: Apache's current design doesn't allow a pool to be passed thru, - so we depend on a global to hold the correct pool -*/ -#define FILTER_POOL apr_hook_global_pool -#include "apr_hooks.h" /* for apr_hook_global_pool */ - -/* -** This macro returns true/false if a given filter should be inserted BEFORE -** another filter. This will happen when one of: 1) there isn't another -** filter; 2) that filter has a higher filter type (class); 3) that filter -** corresponds to a different request. -*/ -#define INSERT_BEFORE(f, before_this) ((before_this) == NULL \ - || (before_this)->frec->ftype > (f)->frec->ftype \ - || (before_this)->r != (f)->r) - -/* Trie structure to hold the mapping from registered - * filter names to filters - */ - -typedef struct filter_trie_node filter_trie_node; - -typedef struct { - int c; - filter_trie_node *child; -} filter_trie_child_ptr; - -/* Each trie node has an array of pointers to its children. - * The array is kept in sorted order so that add_any_filter() - * can do a binary search - */ -struct filter_trie_node { - ap_filter_rec_t *frec; - filter_trie_child_ptr *children; - int nchildren; - int size; -}; - -#define TRIE_INITIAL_SIZE 4 - -/* Link a trie node to its parent - */ -static void trie_node_link(apr_pool_t *p, filter_trie_node *parent, - filter_trie_node *child, int c) -{ - int i, j; - - if (parent->nchildren == parent->size) { - filter_trie_child_ptr *new; - parent->size *= 2; - new = (filter_trie_child_ptr *)apr_palloc(p, parent->size * - sizeof(filter_trie_child_ptr)); - memcpy(new, parent->children, parent->nchildren * - sizeof(filter_trie_child_ptr)); - parent->children = new; - } - - for (i = 0; i < parent->nchildren; i++) { - if (c == parent->children[i].c) { - return; - } - else if (c < parent->children[i].c) { - break; - } - } - for (j = parent->nchildren; j > i; j--) { - parent->children[j].c = parent->children[j - 1].c; - parent->children[j].child = parent->children[j - 1].child; - } - parent->children[i].c = c; - parent->children[i].child = child; - - parent->nchildren++; -} - -/* Allocate a new node for a trie. - * If parent is non-NULL, link the new node under the parent node with - * key 'c' (or, if an existing child node matches, return that one) - */ -static filter_trie_node *trie_node_alloc(apr_pool_t *p, - filter_trie_node *parent, char c) -{ - filter_trie_node *new_node; - if (parent) { - int i; - for (i = 0; i < parent->nchildren; i++) { - if (c == parent->children[i].c) { - return parent->children[i].child; - } - else if (c < parent->children[i].c) { - break; - } - } - new_node = - (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node)); - trie_node_link(p, parent, new_node, c); - } - else { /* No parent node */ - new_node = (filter_trie_node *)apr_palloc(p, - sizeof(filter_trie_node)); - } - - new_node->frec = NULL; - new_node->nchildren = 0; - new_node->size = TRIE_INITIAL_SIZE; - new_node->children = (filter_trie_child_ptr *)apr_palloc(p, - new_node->size * sizeof(filter_trie_child_ptr)); - return new_node; -} - -static filter_trie_node *registered_output_filters = NULL; -static filter_trie_node *registered_input_filters = NULL; - - -static apr_status_t filter_cleanup(void *ctx) -{ - registered_output_filters = NULL; - registered_input_filters = NULL; - return APR_SUCCESS; -} - -static ap_filter_rec_t *get_filter_handle(const char *name, - const filter_trie_node *filter_set) -{ - if (filter_set) { - const char *n; - const filter_trie_node *node; - - node = filter_set; - for (n = name; *n; n++) { - int start, end; - start = 0; - end = node->nchildren - 1; - while (end >= start) { - int middle = (end + start) / 2; - char ch = node->children[middle].c; - if (*n == ch) { - node = node->children[middle].child; - break; - } - else if (*n < ch) { - end = middle - 1; - } - else { - start = middle + 1; - } - } - if (end < start) { - node = NULL; - break; - } - } - - if (node && node->frec) { - return node->frec; - } - } - return NULL; -} - -AP_DECLARE(ap_filter_rec_t *)ap_get_output_filter_handle(const char *name) -{ - return get_filter_handle(name, registered_output_filters); -} - -AP_DECLARE(ap_filter_rec_t *)ap_get_input_filter_handle(const char *name) -{ - return get_filter_handle(name, registered_input_filters); -} - -static ap_filter_rec_t *register_filter(const char *name, - ap_filter_func filter_func, - ap_init_filter_func filter_init, - ap_filter_type ftype, - filter_trie_node **reg_filter_set) -{ - ap_filter_rec_t *frec; - char *normalized_name; - const char *n; - filter_trie_node *node; - - if (!*reg_filter_set) { - *reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0); - } - - normalized_name = apr_pstrdup(FILTER_POOL, name); - ap_str_tolower(normalized_name); - - node = *reg_filter_set; - for (n = normalized_name; *n; n++) { - filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n); - if (apr_isalpha(*n)) { - trie_node_link(FILTER_POOL, node, child, apr_toupper(*n)); - } - node = child; - } - if (node->frec) { - frec = node->frec; - } - else { - frec = apr_palloc(FILTER_POOL, sizeof(*frec)); - node->frec = frec; - frec->name = normalized_name; - } - frec->filter_func = filter_func; - frec->filter_init_func = filter_init; - frec->ftype = ftype; - - apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup, - apr_pool_cleanup_null); - return frec; -} - -AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name, - ap_in_filter_func filter_func, - ap_init_filter_func filter_init, - ap_filter_type ftype) -{ - ap_filter_func f; - f.in_func = filter_func; - return register_filter(name, f, filter_init, ftype, - ®istered_input_filters); -} - -AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name, - ap_out_filter_func filter_func, - ap_init_filter_func filter_init, - ap_filter_type ftype) -{ - ap_filter_func f; - f.out_func = filter_func; - return register_filter(name, f, filter_init, ftype, - ®istered_output_filters); -} - -static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx, - request_rec *r, conn_rec *c, - ap_filter_t **r_filters, - ap_filter_t **p_filters, - ap_filter_t **c_filters) -{ - apr_pool_t* p = r ? r->pool : c->pool; - ap_filter_t *f = apr_palloc(p, sizeof(*f)); - ap_filter_t **outf; - - if (frec->ftype < AP_FTYPE_PROTOCOL) { - if (r) { - outf = r_filters; - } - else { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "a content filter was added without a request: %s", frec->name); - return NULL; - } - } - else if (frec->ftype < AP_FTYPE_CONNECTION) { - if (r) { - outf = p_filters; - } - else { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "a protocol filter was added without a request: %s", frec->name); - return NULL; - } - } - else { - outf = c_filters; - } - - f->frec = frec; - f->ctx = ctx; - f->r = r; - f->c = c; - f->next = NULL; - - if (INSERT_BEFORE(f, *outf)) { - f->next = *outf; - - if (*outf) { - ap_filter_t *first = NULL; - - if (r) { - /* If we are adding our first non-connection filter, - * Then don't try to find the right location, it is - * automatically first. - */ - if (*r_filters != *c_filters) { - first = *r_filters; - while (first && (first->next != (*outf))) { - first = first->next; - } - } - } - if (first && first != (*outf)) { - first->next = f; - } - } - *outf = f; - } - else { - ap_filter_t *fscan = *outf; - while (!INSERT_BEFORE(f, fscan->next)) - fscan = fscan->next; - - f->next = fscan->next; - fscan->next = f; - } - - if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) { - *r_filters = *p_filters; - } - return f; -} - -static ap_filter_t *add_any_filter(const char *name, void *ctx, - request_rec *r, conn_rec *c, - const filter_trie_node *reg_filter_set, - ap_filter_t **r_filters, - ap_filter_t **p_filters, - ap_filter_t **c_filters) -{ - if (reg_filter_set) { - const char *n; - const filter_trie_node *node; - - node = reg_filter_set; - for (n = name; *n; n++) { - int start, end; - start = 0; - end = node->nchildren - 1; - while (end >= start) { - int middle = (end + start) / 2; - char ch = node->children[middle].c; - if (*n == ch) { - node = node->children[middle].child; - break; - } - else if (*n < ch) { - end = middle - 1; - } - else { - start = middle + 1; - } - } - if (end < start) { - node = NULL; - break; - } - } - - if (node && node->frec) { - return add_any_filter_handle(node->frec, ctx, r, c, r_filters, - p_filters, c_filters); - } - } - - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "an unknown filter was not added: %s", name); - return NULL; -} - -AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, - request_rec *r, conn_rec *c) -{ - return add_any_filter(name, ctx, r, c, registered_input_filters, - r ? &r->input_filters : NULL, - r ? &r->proto_input_filters : NULL, &c->input_filters); -} - -AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f, - void *ctx, - request_rec *r, - conn_rec *c) -{ - return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL, - r ? &r->proto_input_filters : NULL, - &c->input_filters); -} - -AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, - request_rec *r, conn_rec *c) -{ - return add_any_filter(name, ctx, r, c, registered_output_filters, - r ? &r->output_filters : NULL, - r ? &r->proto_output_filters : NULL, &c->output_filters); -} - -AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f, - void *ctx, - request_rec *r, - conn_rec *c) -{ - return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL, - r ? &r->proto_output_filters : NULL, - &c->output_filters); -} - -static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt, - ap_filter_t **c_filt) -{ - ap_filter_t **curr = r_filt ? r_filt : c_filt; - ap_filter_t *fscan = *curr; - - if (p_filt && *p_filt == f) - *p_filt = (*p_filt)->next; - - if (*curr == f) { - *curr = (*curr)->next; - return; - } - - while (fscan->next != f) { - if (!(fscan = fscan->next)) { - return; - } - } - - fscan->next = f->next; -} - -AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f) -{ - remove_any_filter(f, f->r ? &f->r->input_filters : NULL, - f->r ? &f->r->proto_input_filters : NULL, - &f->c->input_filters); -} - -AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f) -{ - remove_any_filter(f, f->r ? &f->r->output_filters : NULL, - f->r ? &f->r->proto_output_filters : NULL, - &f->c->output_filters); -} - -/* - * Read data from the next filter in the filter stack. Data should be - * modified in the bucket brigade that is passed in. The core allocates the - * bucket brigade, modules that wish to replace large chunks of data or to - * save data off to the side should probably create their own temporary - * brigade especially for that use. - */ -AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next, - apr_bucket_brigade *bb, - ap_input_mode_t mode, - apr_read_type_e block, - apr_off_t readbytes) -{ - if (next) { - return next->frec->filter_func.in_func(next, bb, mode, block, - readbytes); - } - return AP_NOBODY_READ; -} - -/* Pass the buckets to the next filter in the filter stack. If the - * current filter is a handler, we should get NULL passed in instead of - * the current filter. At that point, we can just call the first filter in - * the stack, or r->output_filters. - */ -AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *next, - apr_bucket_brigade *bb) -{ - if (next) { - apr_bucket *e; - if ((e = APR_BRIGADE_LAST(bb)) && APR_BUCKET_IS_EOS(e) && next->r) { - /* This is only safe because HTTP_HEADER filter is always in - * the filter stack. This ensures that there is ALWAYS a - * request-based filter that we can attach this to. If the - * HTTP_FILTER is removed, and another filter is not put in its - * place, then handlers like mod_cgi, which attach their own - * EOS bucket to the brigade will be broken, because we will - * get two EOS buckets on the same request. - */ - next->r->eos_sent = 1; - - /* remember the eos for internal redirects, too */ - if (next->r->prev) { - request_rec *prev = next->r->prev; - - while (prev) { - prev->eos_sent = 1; - prev = prev->prev; - } - } - } - return next->frec->filter_func.out_func(next, bb); - } - return AP_NOBODY_WROTE; -} - -AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f, - apr_bucket_brigade **saveto, - apr_bucket_brigade **b, apr_pool_t *p) -{ - apr_bucket *e; - apr_status_t rv, srv = APR_SUCCESS; - - /* If have never stored any data in the filter, then we had better - * create an empty bucket brigade so that we can concat. - */ - if (!(*saveto)) { - *saveto = apr_brigade_create(p, f->c->bucket_alloc); - } - - APR_RING_FOREACH(e, &(*b)->list, apr_bucket, link) { - rv = apr_bucket_setaside(e, p); - - /* If the bucket type does not implement setaside, then - * (hopefully) morph it into a bucket type which does, and set - * *that* aside... */ - if (rv == APR_ENOTIMPL) { - const char *s; - apr_size_t n; - - rv = apr_bucket_read(e, &s, &n, APR_BLOCK_READ); - if (rv == APR_SUCCESS) { - rv = apr_bucket_setaside(e, p); - } - } - - if (rv != APR_SUCCESS) { - srv = rv; - /* Return an error but still save the brigade if - * ->setaside() is really not implemented. */ - if (rv != APR_ENOTIMPL) { - return rv; - } - } - } - APR_BRIGADE_CONCAT(*saveto, *b); - return srv; -} - -AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb, - void *ctx) -{ - ap_filter_t *f = ctx; - - return ap_pass_brigade(f, bb); -} - -AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb) -{ - apr_bucket *b; - - b = apr_bucket_flush_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - return ap_pass_brigade(f, bb); -} - -AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f, - apr_bucket_brigade *bb, ...) -{ - va_list args; - apr_status_t rv; - - va_start(args, bb); - rv = apr_brigade_vputstrs(bb, ap_filter_flush, f, args); - va_end(args); - return rv; -} - -AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f, - apr_bucket_brigade *bb, - const char *fmt, - ...) -{ - va_list args; - apr_status_t rv; - - va_start(args, fmt); - rv = apr_brigade_vprintf(bb, ap_filter_flush, f, fmt, args); - va_end(args); - return rv; -} diff --git a/rubbos/app/httpd-2.0.64/server/util_filter.lo b/rubbos/app/httpd-2.0.64/server/util_filter.lo deleted file mode 100644 index 236b514d..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_filter.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_filter.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_filter.o' - -# Name of the non-PIC object. -non_pic_object='util_filter.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_filter.o b/rubbos/app/httpd-2.0.64/server/util_filter.o Binary files differdeleted file mode 100644 index 80950d79..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_filter.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_md5.c b/rubbos/app/httpd-2.0.64/server/util_md5.c deleted file mode 100644 index b51de062..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_md5.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/************************************************************************ - * NCSA HTTPd Server - * Software Development Group - * National Center for Supercomputing Applications - * University of Illinois at Urbana-Champaign - * 605 E. Springfield, Champaign, IL 61820 - * httpd@ncsa.uiuc.edu - * - * Copyright (C) 1995, Board of Trustees of the University of Illinois - * - ************************************************************************ - * - * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code - * - * Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc. - * Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon - * University (see Copyright below). - * Portions of Content-MD5 code Copyright (C) 1991 Bell Communications - * Research, Inc. (Bellcore) (see Copyright below). - * Portions extracted from mpack, John G. Myers - jgm+@cmu.edu - * Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk) - * - */ - - - -/* md5.c --Module Interface to MD5. */ -/* Jeff Hostetler, Spyglass, Inc., 1994. */ - -#include "ap_config.h" -#include "apr_portable.h" -#include "apr_strings.h" -#include "httpd.h" -#include "util_md5.h" -#include "util_ebcdic.h" - -AP_DECLARE(char *) ap_md5_binary(apr_pool_t *p, const unsigned char *buf, int length) -{ - const char *hex = "0123456789abcdef"; - apr_md5_ctx_t my_md5; - unsigned char hash[MD5_DIGESTSIZE]; - char *r, result[33]; /* (MD5_DIGESTSIZE * 2) + 1 */ - int i; - - /* - * Take the MD5 hash of the string argument. - */ - - apr_md5_init(&my_md5); -#if APR_CHARSET_EBCDIC - apr_md5_set_xlate(&my_md5, ap_hdrs_to_ascii); -#endif - apr_md5_update(&my_md5, buf, (unsigned int)length); - apr_md5_final(hash, &my_md5); - - for (i = 0, r = result; i < MD5_DIGESTSIZE; i++) { - *r++ = hex[hash[i] >> 4]; - *r++ = hex[hash[i] & 0xF]; - } - *r = '\0'; - - return apr_pstrndup(p, result, MD5_DIGESTSIZE*2); -} - -AP_DECLARE(char *) ap_md5(apr_pool_t *p, const unsigned char *string) -{ - return ap_md5_binary(p, string, (int) strlen((char *)string)); -} - -/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */ - -/* (C) Copyright 1993,1994 by Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of Carnegie - * Mellon University not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. Carnegie Mellon University makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore) - * - * Permission to use, copy, modify, and distribute this material - * for any purpose and without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies, and that the name of Bellcore not be - * used in advertising or publicity pertaining to this - * material without the specific, prior written permission - * of an authorized representative of Bellcore. BELLCORE - * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY - * OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", - * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. - */ - -static char basis_64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -AP_DECLARE(char *) ap_md5contextTo64(apr_pool_t *a, apr_md5_ctx_t *context) -{ - unsigned char digest[18]; - char *encodedDigest; - int i; - char *p; - - encodedDigest = (char *) apr_pcalloc(a, 25 * sizeof(char)); - - apr_md5_final(digest, context); - digest[sizeof(digest) - 1] = digest[sizeof(digest) - 2] = 0; - - p = encodedDigest; - for (i = 0; i < sizeof(digest); i += 3) { - *p++ = basis_64[digest[i] >> 2]; - *p++ = basis_64[((digest[i] & 0x3) << 4) | ((int) (digest[i + 1] & 0xF0) >> 4)]; - *p++ = basis_64[((digest[i + 1] & 0xF) << 2) | ((int) (digest[i + 2] & 0xC0) >> 6)]; - *p++ = basis_64[digest[i + 2] & 0x3F]; - } - *p-- = '\0'; - *p-- = '='; - *p-- = '='; - return encodedDigest; -} - -AP_DECLARE(char *) ap_md5digest(apr_pool_t *p, apr_file_t *infile) -{ - apr_md5_ctx_t context; - unsigned char buf[1000]; - long length = 0; - apr_size_t nbytes; - apr_off_t offset = 0L; - - apr_md5_init(&context); - nbytes = sizeof(buf); - while (apr_file_read(infile, buf, &nbytes) == APR_SUCCESS) { - length += nbytes; - apr_md5_update(&context, buf, nbytes); - } - apr_file_seek(infile, APR_SET, &offset); - return ap_md5contextTo64(p, &context); -} - diff --git a/rubbos/app/httpd-2.0.64/server/util_md5.lo b/rubbos/app/httpd-2.0.64/server/util_md5.lo deleted file mode 100644 index 246935a9..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_md5.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_md5.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_md5.o' - -# Name of the non-PIC object. -non_pic_object='util_md5.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_md5.o b/rubbos/app/httpd-2.0.64/server/util_md5.o Binary files differdeleted file mode 100644 index 172bfbf4..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_md5.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_script.c b/rubbos/app/httpd-2.0.64/server/util_script.c deleted file mode 100644 index ad8d5745..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_script.c +++ /dev/null @@ -1,717 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr.h" -#include "apr_lib.h" -#include "apr_strings.h" - -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#if APR_HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_main.h" -#include "http_log.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_request.h" /* for sub_req_lookup_uri() */ -#include "util_script.h" -#include "apr_date.h" /* For apr_date_parse_http() */ -#include "util_ebcdic.h" - -#ifdef OS2 -#define INCL_DOS -#include <os2.h> -#endif - -/* - * Various utility functions which are common to a whole lot of - * script-type extensions mechanisms, and might as well be gathered - * in one place (if only to avoid creating inter-module dependancies - * where there don't have to be). - */ - -#define MALFORMED_MESSAGE "malformed header from script. Bad header=" -#define MALFORMED_HEADER_LENGTH_TO_SHOW 30 - -static char *http2env(apr_pool_t *a, const char *w) -{ - char *res = (char *)apr_palloc(a, sizeof("HTTP_") + strlen(w)); - char *cp = res; - char c; - - *cp++ = 'H'; - *cp++ = 'T'; - *cp++ = 'T'; - *cp++ = 'P'; - *cp++ = '_'; - - while ((c = *w++) != 0) { - if (!apr_isalnum(c)) { - *cp++ = '_'; - } - else { - *cp++ = apr_toupper(c); - } - } - *cp = 0; - - return res; -} - -AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t) -{ - const apr_array_header_t *env_arr = apr_table_elts(t); - const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts; - char **env = (char **) apr_palloc(p, (env_arr->nelts + 2) * sizeof(char *)); - int i, j; - char *tz; - char *whack; - - j = 0; - if (!apr_table_get(t, "TZ")) { - tz = getenv("TZ"); - if (tz != NULL) { - env[j++] = apr_pstrcat(p, "TZ=", tz, NULL); - } - } - for (i = 0; i < env_arr->nelts; ++i) { - if (!elts[i].key) { - continue; - } - env[j] = apr_pstrcat(p, elts[i].key, "=", elts[i].val, NULL); - whack = env[j]; - if (apr_isdigit(*whack)) { - *whack++ = '_'; - } - while (*whack != '=') { - if (!apr_isalnum(*whack) && *whack != '_') { - *whack = '_'; - } - ++whack; - } - ++j; - } - - env[j] = NULL; - return env; -} - -AP_DECLARE(void) ap_add_common_vars(request_rec *r) -{ - apr_table_t *e; - server_rec *s = r->server; - conn_rec *c = r->connection; - const char *rem_logname; - char *env_path; -#if defined(WIN32) || defined(OS2) || defined(BEOS) - char *env_temp; -#endif - const char *host; - const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in); - const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts; - int i; - apr_port_t rport; - - /* use a temporary apr_table_t which we'll overlap onto - * r->subprocess_env later - * (exception: if r->subprocess_env is empty at the start, - * write directly into it) - */ - if (apr_is_empty_table(r->subprocess_env)) { - e = r->subprocess_env; - } - else { - e = apr_table_make(r->pool, 25 + hdrs_arr->nelts); - } - - /* First, add environment vars from headers... this is as per - * CGI specs, though other sorts of scripting interfaces see - * the same vars... - */ - - for (i = 0; i < hdrs_arr->nelts; ++i) { - if (!hdrs[i].key) { - continue; - } - - /* A few headers are special cased --- Authorization to prevent - * rogue scripts from capturing passwords; content-type and -length - * for no particular reason. - */ - - if (!strcasecmp(hdrs[i].key, "Content-type")) { - apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val); - } - else if (!strcasecmp(hdrs[i].key, "Content-length")) { - apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val); - } - /* - * You really don't want to disable this check, since it leaves you - * wide open to CGIs stealing passwords and people viewing them - * in the environment with "ps -e". But, if you must... - */ -#ifndef SECURITY_HOLE_PASS_AUTHORIZATION - else if (!strcasecmp(hdrs[i].key, "Authorization") - || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) { - continue; - } -#endif - else { - apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val); - } - } - - if (!(env_path = getenv("PATH"))) { - env_path = DEFAULT_PATH; - } - apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path)); - -#ifdef WIN32 - if (env_temp = getenv("SystemRoot")) { - apr_table_addn(e, "SystemRoot", env_temp); - } - if (env_temp = getenv("COMSPEC")) { - apr_table_addn(e, "COMSPEC", env_temp); - } - if (env_temp = getenv("PATHEXT")) { - apr_table_addn(e, "PATHEXT", env_temp); - } - if (env_temp = getenv("WINDIR")) { - apr_table_addn(e, "WINDIR", env_temp); - } -#endif - -#ifdef OS2 - if ((env_temp = getenv("COMSPEC")) != NULL) { - apr_table_addn(e, "COMSPEC", env_temp); - } - if ((env_temp = getenv("ETC")) != NULL) { - apr_table_addn(e, "ETC", env_temp); - } - if ((env_temp = getenv("DPATH")) != NULL) { - apr_table_addn(e, "DPATH", env_temp); - } - if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) { - apr_table_addn(e, "PERLLIB_PREFIX", env_temp); - } -#endif - -#ifdef BEOS - if ((env_temp = getenv("LIBRARY_PATH")) != NULL) { - apr_table_addn(e, "LIBRARY_PATH", env_temp); - } -#endif - - apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); - apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version()); - apr_table_addn(e, "SERVER_NAME", - ap_escape_html(r->pool, ap_get_server_name(r))); - apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */ - apr_table_addn(e, "SERVER_PORT", - apr_psprintf(r->pool, "%u", ap_get_server_port(r))); - host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL); - if (host) { - apr_table_addn(e, "REMOTE_HOST", host); - } - apr_table_addn(e, "REMOTE_ADDR", c->remote_ip); - apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */ - apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */ - apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ - - apr_sockaddr_port_get(&rport, c->remote_addr); - apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport)); - - if (r->user) { - apr_table_addn(e, "REMOTE_USER", r->user); - } - else if (r->prev) { - request_rec *back = r->prev; - - while (back) { - if (back->user) { - apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user); - break; - } - back = back->prev; - } - } - if (r->ap_auth_type) { - apr_table_addn(e, "AUTH_TYPE", r->ap_auth_type); - } - rem_logname = ap_get_remote_logname(r); - if (rem_logname) { - apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname)); - } - - /* Apache custom error responses. If we have redirected set two new vars */ - - if (r->prev) { - if (r->prev->args) { - apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args); - } - if (r->prev->uri) { - apr_table_addn(e, "REDIRECT_URL", r->prev->uri); - } - } - - if (e != r->subprocess_env) { - apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET); - } -} - -/* This "cute" little function comes about because the path info on - * filenames and URLs aren't always the same. So we take the two, - * and find as much of the two that match as possible. - */ - -AP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info) -{ - int lu = strlen(uri); - int lp = strlen(path_info); - - while (lu-- && lp-- && uri[lu] == path_info[lp]); - - if (lu == -1) { - lu = 0; - } - - while (uri[lu] != '\0' && uri[lu] != '/') { - lu++; - } - return lu; -} - -/* Obtain the Request-URI from the original request-line, returning - * a new string from the request pool containing the URI or "". - */ -static char *original_uri(request_rec *r) -{ - char *first, *last; - - if (r->the_request == NULL) { - return (char *) apr_pcalloc(r->pool, 1); - } - - first = r->the_request; /* use the request-line */ - - while (*first && !apr_isspace(*first)) { - ++first; /* skip over the method */ - } - while (apr_isspace(*first)) { - ++first; /* and the space(s) */ - } - - last = first; - while (*last && !apr_isspace(*last)) { - ++last; /* end at next whitespace */ - } - - return apr_pstrmemdup(r->pool, first, last - first); -} - -AP_DECLARE(void) ap_add_cgi_vars(request_rec *r) -{ - apr_table_t *e = r->subprocess_env; - - apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1"); - apr_table_setn(e, "SERVER_PROTOCOL", r->protocol); - apr_table_setn(e, "REQUEST_METHOD", r->method); - apr_table_setn(e, "QUERY_STRING", r->args ? r->args : ""); - apr_table_setn(e, "REQUEST_URI", original_uri(r)); - - /* Note that the code below special-cases scripts run from includes, - * because it "knows" that the sub_request has been hacked to have the - * args and path_info of the original request, and not any that may have - * come with the script URI in the include command. Ugh. - */ - - if (!strcmp(r->protocol, "INCLUDED")) { - apr_table_setn(e, "SCRIPT_NAME", r->uri); - if (r->path_info && *r->path_info) { - apr_table_setn(e, "PATH_INFO", r->path_info); - } - } - else if (!r->path_info || !*r->path_info) { - apr_table_setn(e, "SCRIPT_NAME", r->uri); - } - else { - int path_info_start = ap_find_path_info(r->uri, r->path_info); - - apr_table_setn(e, "SCRIPT_NAME", - apr_pstrndup(r->pool, r->uri, path_info_start)); - - apr_table_setn(e, "PATH_INFO", r->path_info); - } - - if (r->path_info && r->path_info[0]) { - /* - * To get PATH_TRANSLATED, treat PATH_INFO as a URI path. - * Need to re-escape it for this, since the entire URI was - * un-escaped before we determined where the PATH_INFO began. - */ - request_rec *pa_req; - - pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), r, - NULL); - - if (pa_req->filename) { - char *pt = apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info, - NULL); -#ifdef WIN32 - /* We need to make this a real Windows path name */ - apr_filepath_merge(&pt, "", pt, APR_FILEPATH_NATIVE, r->pool); -#endif - apr_table_setn(e, "PATH_TRANSLATED", pt); - } - ap_destroy_sub_req(pa_req); - } -} - - -static int set_cookie_doo_doo(void *v, const char *key, const char *val) -{ - apr_table_addn(v, key, val); - return 1; -} - -#define HTTP_UNSET (-HTTP_OK) - -AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, - int (*getsfunc) (char *, int, void *), - void *getsfunc_data) -{ - char x[MAX_STRING_LEN]; - char *w, *l; - int p; - int cgi_status = HTTP_UNSET; - apr_table_t *merge; - apr_table_t *cookie_table; - - if (buffer) { - *buffer = '\0'; - } - w = buffer ? buffer : x; - - /* temporary place to hold headers to merge in later */ - merge = apr_table_make(r->pool, 10); - - /* The HTTP specification says that it is legal to merge duplicate - * headers into one. Some browsers that support Cookies don't like - * merged headers and prefer that each Set-Cookie header is sent - * separately. Lets humour those browsers by not merging. - * Oh what a pain it is. - */ - cookie_table = apr_table_make(r->pool, 2); - apr_table_do(set_cookie_doo_doo, cookie_table, r->err_headers_out, "Set-Cookie", NULL); - - while (1) { - - if ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data) == 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, - "Premature end of script headers: %s", - apr_filename_of_pathname(r->filename)); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* Delete terminal (CR?)LF */ - - p = strlen(w); - /* Indeed, the host's '\n': - '\012' for UNIX; '\015' for MacOS; '\025' for OS/390 - -- whatever the script generates. - */ - if (p > 0 && w[p - 1] == '\n') { - if (p > 1 && w[p - 2] == CR) { - w[p - 2] = '\0'; - } - else { - w[p - 1] = '\0'; - } - } - - /* - * If we've finished reading the headers, check to make sure any - * HTTP/1.1 conditions are met. If so, we're done; normal processing - * will handle the script's output. If not, just return the error. - * The appropriate thing to do would be to send the script process a - * SIGPIPE to let it know we're ignoring it, close the channel to the - * script process, and *then* return the failed-to-meet-condition - * error. Otherwise we'd be waiting for the script to finish - * blithering before telling the client the output was no good. - * However, we don't have the information to do that, so we have to - * leave it to an upper layer. - */ - if (w[0] == '\0') { - int cond_status = OK; - - /* PR#38070: This fails because it gets confused when a - * CGI Status header overrides ap_meets_conditions. - * - * We can fix that by dropping ap_meets_conditions when - * Status has been set. Since this is the only place - * cgi_status gets used, let's test it explicitly. - * - * The alternative would be to ignore CGI Status when - * ap_meets_conditions returns anything interesting. - * That would be safer wrt HTTP, but would break CGI. - */ - if ((cgi_status == HTTP_UNSET) && (r->method_number == M_GET)) { - cond_status = ap_meets_conditions(r); - } - apr_table_overlap(r->err_headers_out, merge, - APR_OVERLAP_TABLES_MERGE); - if (!apr_is_empty_table(cookie_table)) { - /* the cookies have already been copied to the cookie_table */ - apr_table_unset(r->err_headers_out, "Set-Cookie"); - r->err_headers_out = apr_table_overlay(r->pool, - r->err_headers_out, cookie_table); - } - return cond_status; - } - - /* if we see a bogus header don't ignore it. Shout and scream */ - -#if APR_CHARSET_EBCDIC - /* Chances are that we received an ASCII header text instead of - * the expected EBCDIC header lines. Try to auto-detect: - */ - if (!(l = strchr(w, ':'))) { - int maybeASCII = 0, maybeEBCDIC = 0; - unsigned char *cp, native; - apr_size_t inbytes_left, outbytes_left; - - for (cp = w; *cp != '\0'; ++cp) { - native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp); - if (apr_isprint(*cp) && !apr_isprint(native)) - ++maybeEBCDIC; - if (!apr_isprint(*cp) && apr_isprint(native)) - ++maybeASCII; - } - if (maybeASCII > maybeEBCDIC) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)", - r->filename); - inbytes_left = outbytes_left = cp - w; - apr_xlate_conv_buffer(ap_hdrs_from_ascii, - w, &inbytes_left, w, &outbytes_left); - } - } -#endif /*APR_CHARSET_EBCDIC*/ - if (!(l = strchr(w, ':'))) { - char malformed[(sizeof MALFORMED_MESSAGE) + 1 - + MALFORMED_HEADER_LENGTH_TO_SHOW]; - - strcpy(malformed, MALFORMED_MESSAGE); - strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW); - - if (!buffer) { - /* Soak up all the script output - may save an outright kill */ - while ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data)) { - continue; - } - } - - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, - "%s: %s", malformed, - apr_filename_of_pathname(r->filename)); - return HTTP_INTERNAL_SERVER_ERROR; - } - - *l++ = '\0'; - while (*l && apr_isspace(*l)) { - ++l; - } - - if (!strcasecmp(w, "Content-type")) { - char *tmp; - - /* Nuke trailing whitespace */ - - char *endp = l + strlen(l) - 1; - while (endp > l && apr_isspace(*endp)) { - *endp-- = '\0'; - } - - tmp = apr_pstrdup(r->pool, l); - ap_content_type_tolower(tmp); - ap_set_content_type(r, tmp); - } - /* - * If the script returned a specific status, that's what - * we'll use - otherwise we assume 200 OK. - */ - else if (!strcasecmp(w, "Status")) { - r->status = cgi_status = atoi(l); - r->status_line = apr_pstrdup(r->pool, l); - } - else if (!strcasecmp(w, "Location")) { - apr_table_set(r->headers_out, w, l); - } - else if (!strcasecmp(w, "Content-Length")) { - apr_table_set(r->headers_out, w, l); - } - else if (!strcasecmp(w, "Content-Range")) { - apr_table_set(r->headers_out, w, l); - } - else if (!strcasecmp(w, "Transfer-Encoding")) { - apr_table_set(r->headers_out, w, l); - } - /* - * If the script gave us a Last-Modified header, we can't just - * pass it on blindly because of restrictions on future values. - */ - else if (!strcasecmp(w, "Last-Modified")) { - ap_update_mtime(r, apr_date_parse_http(l)); - ap_set_last_modified(r); - } - else if (!strcasecmp(w, "Set-Cookie")) { - apr_table_add(cookie_table, w, l); - } - else { - apr_table_add(merge, w, l); - } - } - - return OK; -} - -static int getsfunc_FILE(char *buf, int len, void *f) -{ - return apr_file_gets(buf, len, (apr_file_t *) f) == APR_SUCCESS; -} - -AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, - char *buffer) -{ - return ap_scan_script_header_err_core(r, buffer, getsfunc_FILE, f); -} - -static int getsfunc_BRIGADE(char *buf, int len, void *arg) -{ - apr_bucket_brigade *bb = (apr_bucket_brigade *)arg; - const char *dst_end = buf + len - 1; /* leave room for terminating null */ - char *dst = buf; - apr_bucket *e = APR_BRIGADE_FIRST(bb); - apr_status_t rv; - int done = 0; - - while ((dst < dst_end) && !done && !APR_BUCKET_IS_EOS(e)) { - const char *bucket_data; - apr_size_t bucket_data_len; - const char *src; - const char *src_end; - apr_bucket * next; - - rv = apr_bucket_read(e, &bucket_data, &bucket_data_len, - APR_BLOCK_READ); - if (!APR_STATUS_IS_SUCCESS(rv) || (bucket_data_len == 0)) { - return 0; - } - src = bucket_data; - src_end = bucket_data + bucket_data_len; - while ((src < src_end) && (dst < dst_end) && !done) { - if (*src == '\n') { - done = 1; - } - else if (*src != '\r') { - *dst++ = *src; - } - src++; - } - - if (src < src_end) { - apr_bucket_split(e, src - bucket_data); - } - next = APR_BUCKET_NEXT(e); - APR_BUCKET_REMOVE(e); - apr_bucket_destroy(e); - e = next; - } - *dst = 0; - return 1; -} - -AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r, - apr_bucket_brigade *bb, - char *buffer) -{ - return ap_scan_script_header_err_core(r, buffer, getsfunc_BRIGADE, bb); -} - -struct vastrs { - va_list args; - int arg; - const char *curpos; -}; - -static int getsfunc_STRING(char *w, int len, void *pvastrs) -{ - struct vastrs *strs = (struct vastrs*) pvastrs; - const char *p; - int t; - - if (!strs->curpos || !*strs->curpos) - return 0; - p = ap_strchr_c(strs->curpos, '\n'); - if (p) - ++p; - else - p = ap_strchr_c(strs->curpos, '\0'); - t = p - strs->curpos; - if (t > len) - t = len; - strncpy (w, strs->curpos, t); - w[t] = '\0'; - if (!strs->curpos[t]) { - ++strs->arg; - strs->curpos = va_arg(strs->args, const char *); - } - else - strs->curpos += t; - return t; -} - -/* ap_scan_script_header_err_strs() accepts additional const char* args... - * each is treated as one or more header lines, and the first non-header - * character is returned to **arg, **data. (The first optional arg is - * counted as 0.) - */ -AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, - char *buffer, - const char **termch, - int *termarg, ...) -{ - struct vastrs strs; - int res; - - va_start(strs.args, termarg); - strs.arg = 0; - strs.curpos = va_arg(strs.args, char*); - res = ap_scan_script_header_err_core(r, buffer, getsfunc_STRING, (void *) &strs); - if (termch) - *termch = strs.curpos; - if (termarg) - *termarg = strs.arg; - va_end(strs.args); - return res; -} diff --git a/rubbos/app/httpd-2.0.64/server/util_script.lo b/rubbos/app/httpd-2.0.64/server/util_script.lo deleted file mode 100644 index 8a9ff660..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_script.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_script.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_script.o' - -# Name of the non-PIC object. -non_pic_object='util_script.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_script.o b/rubbos/app/httpd-2.0.64/server/util_script.o Binary files differdeleted file mode 100644 index 3e7d092e..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_script.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_time.c b/rubbos/app/httpd-2.0.64/server/util_time.c deleted file mode 100644 index e5a488ef..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_time.c +++ /dev/null @@ -1,240 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "util_time.h" - -/* Cache for exploded values of recent timestamps - */ - -struct exploded_time_cache_element { - apr_int64_t t; - apr_time_exp_t xt; - apr_int64_t t_validate; /* please see comments in cached_explode() */ -}; - -/* the "+ 1" is for the current second: */ -#define TIME_CACHE_SIZE (AP_TIME_RECENT_THRESHOLD + 1) - -/* Note that AP_TIME_RECENT_THRESHOLD is defined to - * be a power of two minus one in util_time.h, so that - * we can replace a modulo operation with a bitwise AND - * when hashing items into a cache of size - * AP_TIME_RECENT_THRESHOLD+1 - */ -#define TIME_CACHE_MASK (AP_TIME_RECENT_THRESHOLD) - -static struct exploded_time_cache_element exploded_cache_localtime[TIME_CACHE_SIZE]; -static struct exploded_time_cache_element exploded_cache_gmt[TIME_CACHE_SIZE]; - - -static apr_status_t cached_explode(apr_time_exp_t *xt, apr_time_t t, - struct exploded_time_cache_element *cache, - int use_gmt) -{ - apr_int64_t seconds = apr_time_sec(t); - struct exploded_time_cache_element *cache_element = - &(cache[seconds & TIME_CACHE_MASK]); - struct exploded_time_cache_element cache_element_snapshot; - - /* The cache is implemented as a ring buffer. Each second, - * it uses a different element in the buffer. The timestamp - * in the element indicates whether the element contains the - * exploded time for the current second (vs the time - * 'now - AP_TIME_RECENT_THRESHOLD' seconds ago). If the - * cached value is for the current time, we use it. Otherwise, - * we compute the apr_time_exp_t and store it in this - * cache element. Note that the timestamp in the cache - * element is updated only after the exploded time. Thus - * if two threads hit this cache element simultaneously - * at the start of a new second, they'll both explode the - * time and store it. I.e., the writers will collide, but - * they'll be writing the same value. - */ - if (cache_element->t >= seconds) { - /* There is an intentional race condition in this design: - * in a multithreaded app, one thread might be reading - * from this cache_element to resolve a timestamp from - * TIME_CACHE_SIZE seconds ago at the same time that - * another thread is copying the exploded form of the - * current time into the same cache_element. (I.e., the - * first thread might hit this element of the ring buffer - * just as the element is being recycled.) This can - * also happen at the start of a new second, if a - * reader accesses the cache_element after a writer - * has updated cache_element.t but before the writer - * has finished updating the whole cache_element. - * - * Rather than trying to prevent this race condition - * with locks, we allow it to happen and then detect - * and correct it. The detection works like this: - * Step 1: Take a "snapshot" of the cache element by - * copying it into a temporary buffer. - * Step 2: Check whether the snapshot contains consistent - * data: the timestamps at the start and end of - * the cache_element should both match the 'seconds' - * value that we computed from the input time. - * If these three don't match, then the snapshot - * shows the cache_element in the middle of an - * update, and its contents are invalid. - * Step 3: If the snapshot is valid, use it. Otherwise, - * just give up on the cache and explode the - * input time. - */ - memcpy(&cache_element_snapshot, cache_element, - sizeof(struct exploded_time_cache_element)); - if ((seconds != cache_element_snapshot.t) || - (seconds != cache_element_snapshot.t_validate)) { - /* Invalid snapshot */ - if (use_gmt) { - return apr_time_exp_gmt(xt, t); - } - else { - return apr_time_exp_lt(xt, t); - } - } - else { - /* Valid snapshot */ - memcpy(xt, &(cache_element_snapshot.xt), - sizeof(apr_time_exp_t)); - } - } - else { - apr_status_t r; - if (use_gmt) { - r = apr_time_exp_gmt(xt, t); - } - else { - r = apr_time_exp_lt(xt, t); - } - if (!APR_STATUS_IS_SUCCESS(r)) { - return r; - } - cache_element->t = seconds; - memcpy(&(cache_element->xt), xt, sizeof(apr_time_exp_t)); - cache_element->t_validate = seconds; - } - xt->tm_usec = (int)apr_time_usec(t); - return APR_SUCCESS; -} - - -AP_DECLARE(apr_status_t) ap_explode_recent_localtime(apr_time_exp_t * tm, - apr_time_t t) -{ - return cached_explode(tm, t, exploded_cache_localtime, 0); -} - -AP_DECLARE(apr_status_t) ap_explode_recent_gmt(apr_time_exp_t * tm, - apr_time_t t) -{ - return cached_explode(tm, t, exploded_cache_gmt, 1); -} - -AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t) -{ - /* ### This code is a clone of apr_ctime(), except that it - * uses ap_explode_recent_localtime() instead of apr_time_exp_lt(). - */ - apr_time_exp_t xt; - const char *s; - int real_year; - - /* example: "Wed Jun 30 21:49:08 1993" */ - /* 123456789012345678901234 */ - - ap_explode_recent_localtime(&xt, t); - s = &apr_day_snames[xt.tm_wday][0]; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = ' '; - s = &apr_month_snames[xt.tm_mon][0]; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = ' '; - *date_str++ = xt.tm_mday / 10 + '0'; - *date_str++ = xt.tm_mday % 10 + '0'; - *date_str++ = ' '; - *date_str++ = xt.tm_hour / 10 + '0'; - *date_str++ = xt.tm_hour % 10 + '0'; - *date_str++ = ':'; - *date_str++ = xt.tm_min / 10 + '0'; - *date_str++ = xt.tm_min % 10 + '0'; - *date_str++ = ':'; - *date_str++ = xt.tm_sec / 10 + '0'; - *date_str++ = xt.tm_sec % 10 + '0'; - *date_str++ = ' '; - real_year = 1900 + xt.tm_year; - *date_str++ = real_year / 1000 + '0'; - *date_str++ = real_year % 1000 / 100 + '0'; - *date_str++ = real_year % 100 / 10 + '0'; - *date_str++ = real_year % 10 + '0'; - *date_str++ = 0; - - return APR_SUCCESS; -} - -AP_DECLARE(apr_status_t) ap_recent_rfc822_date(char *date_str, apr_time_t t) -{ - /* ### This code is a clone of apr_rfc822_date(), except that it - * uses ap_explode_recent_gmt() instead of apr_time_exp_gmt(). - */ - apr_time_exp_t xt; - const char *s; - int real_year; - - ap_explode_recent_gmt(&xt, t); - - /* example: "Sat, 08 Jan 2000 18:31:41 GMT" */ - /* 12345678901234567890123456789 */ - - s = &apr_day_snames[xt.tm_wday][0]; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = ','; - *date_str++ = ' '; - *date_str++ = xt.tm_mday / 10 + '0'; - *date_str++ = xt.tm_mday % 10 + '0'; - *date_str++ = ' '; - s = &apr_month_snames[xt.tm_mon][0]; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = *s++; - *date_str++ = ' '; - real_year = 1900 + xt.tm_year; - /* This routine isn't y10k ready. */ - *date_str++ = real_year / 1000 + '0'; - *date_str++ = real_year % 1000 / 100 + '0'; - *date_str++ = real_year % 100 / 10 + '0'; - *date_str++ = real_year % 10 + '0'; - *date_str++ = ' '; - *date_str++ = xt.tm_hour / 10 + '0'; - *date_str++ = xt.tm_hour % 10 + '0'; - *date_str++ = ':'; - *date_str++ = xt.tm_min / 10 + '0'; - *date_str++ = xt.tm_min % 10 + '0'; - *date_str++ = ':'; - *date_str++ = xt.tm_sec / 10 + '0'; - *date_str++ = xt.tm_sec % 10 + '0'; - *date_str++ = ' '; - *date_str++ = 'G'; - *date_str++ = 'M'; - *date_str++ = 'T'; - *date_str++ = 0; - return APR_SUCCESS; -} diff --git a/rubbos/app/httpd-2.0.64/server/util_time.lo b/rubbos/app/httpd-2.0.64/server/util_time.lo deleted file mode 100644 index 138d3cb3..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_time.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_time.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_time.o' - -# Name of the non-PIC object. -non_pic_object='util_time.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_time.o b/rubbos/app/httpd-2.0.64/server/util_time.o Binary files differdeleted file mode 100644 index b3ca86f4..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_time.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/util_xml.c b/rubbos/app/httpd-2.0.64/server/util_xml.c deleted file mode 100644 index f5c67edb..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_xml.c +++ /dev/null @@ -1,128 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_xml.h" - -#include "httpd.h" -#include "http_protocol.h" -#include "http_log.h" -#include "http_core.h" - -#include "util_xml.h" - - -/* used for reading input blocks */ -#define READ_BLOCKSIZE 2048 - - -AP_DECLARE(int) ap_xml_parse_input(request_rec * r, apr_xml_doc **pdoc) -{ - apr_xml_parser *parser; - apr_bucket_brigade *brigade; - int seen_eos; - apr_status_t status; - char errbuf[200]; - apr_size_t total_read = 0; - apr_size_t limit_xml_body = ap_get_limit_xml_body(r); - int result = HTTP_BAD_REQUEST; - - parser = apr_xml_parser_create(r->pool); - brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); - - seen_eos = 0; - total_read = 0; - - do { - apr_bucket *bucket; - - /* read the body, stuffing it into the parser */ - status = ap_get_brigade(r->input_filters, brigade, - AP_MODE_READBYTES, APR_BLOCK_READ, - READ_BLOCKSIZE); - - if (status != APR_SUCCESS) { - goto read_error; - } - - APR_BRIGADE_FOREACH(bucket, brigade) { - const char *data; - apr_size_t len; - - if (APR_BUCKET_IS_EOS(bucket)) { - seen_eos = 1; - break; - } - - if (APR_BUCKET_IS_METADATA(bucket)) { - continue; - } - - status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); - if (status != APR_SUCCESS) { - goto read_error; - } - - total_read += len; - if (limit_xml_body && total_read > limit_xml_body) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "XML request body is larger than the configured " - "limit of %lu", (unsigned long)limit_xml_body); - result = HTTP_REQUEST_ENTITY_TOO_LARGE; - goto read_error; - } - - status = apr_xml_parser_feed(parser, data, len); - if (status) { - goto parser_error; - } - } - - apr_brigade_cleanup(brigade); - } while (!seen_eos); - - apr_brigade_destroy(brigade); - - /* tell the parser that we're done */ - status = apr_xml_parser_done(parser, pdoc); - if (status) { - /* Some parsers are stupid and return an error on blank documents. */ - if (!total_read) { - *pdoc = NULL; - return OK; - } - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "XML parser error (at end). status=%d", status); - return HTTP_BAD_REQUEST; - } - - return OK; - - parser_error: - (void) apr_xml_parser_geterror(parser, errbuf, sizeof(errbuf)); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "%s", errbuf); - - /* FALLTHRU */ - - read_error: - /* make sure the parser is terminated */ - (void) apr_xml_parser_done(parser, NULL); - - apr_brigade_destroy(brigade); - - /* Apache will supply a default error, plus the error log above. */ - return result; -} diff --git a/rubbos/app/httpd-2.0.64/server/util_xml.lo b/rubbos/app/httpd-2.0.64/server/util_xml.lo deleted file mode 100644 index 551eb0d4..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_xml.lo +++ /dev/null @@ -1,12 +0,0 @@ -# util_xml.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/util_xml.o' - -# Name of the non-PIC object. -non_pic_object='util_xml.o' - diff --git a/rubbos/app/httpd-2.0.64/server/util_xml.o b/rubbos/app/httpd-2.0.64/server/util_xml.o Binary files differdeleted file mode 100644 index 295b9bc4..00000000 --- a/rubbos/app/httpd-2.0.64/server/util_xml.o +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/server/vhost.c b/rubbos/app/httpd-2.0.64/server/vhost.c deleted file mode 100644 index edab75a5..00000000 --- a/rubbos/app/httpd-2.0.64/server/vhost.c +++ /dev/null @@ -1,1072 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * http_vhost.c: functions pertaining to virtual host addresses - * (configuration and run-time) - */ - -#include "apr.h" -#include "apr_strings.h" -#include "apr_lib.h" - -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#define CORE_PRIVATE -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "http_vhost.h" -#include "http_protocol.h" -#include "http_core.h" - -#if APR_HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -/* - * After all the definitions there's an explanation of how it's all put - * together. - */ - -/* meta-list of name-vhosts. Each server_rec can be in possibly multiple - * lists of name-vhosts. - */ -typedef struct name_chain name_chain; -struct name_chain { - name_chain *next; - server_addr_rec *sar; /* the record causing it to be in - * this chain (needed for port comparisons) */ - server_rec *server; /* the server to use on a match */ -}; - -/* meta-list of ip addresses. Each server_rec can be in possibly multiple - * hash chains since it can have multiple ips. - */ -typedef struct ipaddr_chain ipaddr_chain; -struct ipaddr_chain { - ipaddr_chain *next; - server_addr_rec *sar; /* the record causing it to be in - * this chain (need for both ip addr and port - * comparisons) */ - server_rec *server; /* the server to use if this matches */ - name_chain *names; /* if non-NULL then a list of name-vhosts - * sharing this address */ -}; - -/* This defines the size of the hash apr_table_t used for hashing ip addresses - * of virtual hosts. It must be a power of two. - */ -#ifndef IPHASH_TABLE_SIZE -#define IPHASH_TABLE_SIZE 256 -#endif - -/* A (n) bucket hash table, each entry has a pointer to a server rec and - * a pointer to the other entries in that bucket. Each individual address, - * even for virtualhosts with multiple addresses, has an entry in this hash - * table. There are extra buckets for _default_, and name-vhost entries. - * - * Note that after config time this is constant, so it is thread-safe. - */ -static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE]; - -/* dump out statistics about the hash function */ -/* #define IPHASH_STATISTICS */ - -/* list of the _default_ servers */ -static ipaddr_chain *default_list; - -/* list of the NameVirtualHost addresses */ -static server_addr_rec *name_vhost_list; -static server_addr_rec **name_vhost_list_tail; - -/* - * How it's used: - * - * The ip address determines which chain in iphash_table is interesting, then - * a comparison is done down that chain to find the first ipaddr_chain whose - * sar matches the address:port pair. - * - * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost. - * - * Otherwise it's a name-vhost list, and the default is the server in the - * ipaddr_chain record. We tuck away the ipaddr_chain record in the - * conn_rec field vhost_lookup_data. Later on after the headers we get a - * second chance, and we use the name_chain to figure out what name-vhost - * matches the headers. - * - * If there was no ip address match in the iphash_table then do a lookup - * in the default_list. - * - * How it's put together ... well you should be able to figure that out - * from how it's used. Or something like that. - */ - - -/* called at the beginning of the config */ -AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p) -{ - memset(iphash_table, 0, sizeof(iphash_table)); - default_list = NULL; - name_vhost_list = NULL; - name_vhost_list_tail = &name_vhost_list; -} - - -/* - * Parses a host of the form <address>[:port] - * paddr is used to create a list in the order of input - * **paddr is the ->next pointer of the last entry (or s->addrs) - * *paddr is the variable used to keep track of **paddr between calls - * port is the default port to assume - */ -static const char *get_addresses(apr_pool_t *p, const char *w_, - server_addr_rec ***paddr, - apr_port_t default_port) -{ - apr_sockaddr_t *my_addr; - server_addr_rec *sar; - char *w, *host, *scope_id; - int wild_port; - apr_size_t wlen; - apr_port_t port; - apr_status_t rv; - - if (*w_ == '\0') - return NULL; - - w = apr_pstrdup(p, w_); - /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */ - wlen = strlen(w); /* wlen must be > 0 at this point */ - wild_port = 0; - if (w[wlen - 1] == '*') { - if (wlen < 2) { - wild_port = 1; - } - else if (w[wlen - 2] == ':') { - w[wlen - 2] = '\0'; - wild_port = 1; - } - } - rv = apr_parse_addr_port(&host, &scope_id, &port, w, p); - /* If the string is "80", apr_parse_addr_port() will be happy and set - * host to NULL and port to 80, so watch out for that. - */ - if (rv != APR_SUCCESS) { - return "The address or port is invalid"; - } - if (!host) { - return "Missing address for VirtualHost"; - } - if (scope_id) { - return "Scope ids are not supported"; - } - if (!port && !wild_port) { - port = default_port; - } - - if (strcmp(host, "*") == 0) { - rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p); - ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */ - } - else if (strcasecmp(host, "_default_") == 0 - || strcmp(host, "255.255.255.255") == 0) { - rv = apr_sockaddr_info_get(&my_addr, "255.255.255.255", APR_INET, port, 0, p); - ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */ - } - else { - rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, - "Cannot resolve host name %s --- ignoring!", host); - return NULL; - } - } - - /* Remember all addresses for the host */ - - do { - sar = apr_pcalloc(p, sizeof(server_addr_rec)); - **paddr = sar; - *paddr = &sar->next; - sar->host_addr = my_addr; - sar->host_port = port; - sar->virthost = host; - my_addr = my_addr->next; - } while (my_addr); - - return NULL; -} - - -/* parse the <VirtualHost> addresses */ -const char *ap_parse_vhost_addrs(apr_pool_t *p, - const char *hostname, - server_rec *s) -{ - server_addr_rec **addrs; - const char *err; - - /* start the list of addreses */ - addrs = &s->addrs; - while (hostname[0]) { - err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port); - if (err) { - *addrs = NULL; - return err; - } - } - /* terminate the list */ - *addrs = NULL; - if (s->addrs) { - if (s->addrs->host_port) { - /* override the default port which is inherited from main_server */ - s->port = s->addrs->host_port; - } - } - return NULL; -} - - -const char *ap_set_name_virtual_host(cmd_parms *cmd, void *dummy, - const char *arg) -{ - /* use whatever port the main server has at this point */ - return get_addresses(cmd->pool, arg, &name_vhost_list_tail, - cmd->server->port); -} - - -/* hash apr_table_t statistics, keep this in here for the beta period so - * we can find out if the hash function is ok - */ -#ifdef IPHASH_STATISTICS -static int iphash_compare(const void *a, const void *b) -{ - return (*(const int *) b - *(const int *) a); -} - - -static void dump_iphash_statistics(server_rec *main_s) -{ - unsigned count[IPHASH_TABLE_SIZE]; - int i; - ipaddr_chain *src; - unsigned total; - char buf[HUGE_STRING_LEN]; - char *p; - - total = 0; - for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { - count[i] = 0; - for (src = iphash_table[i]; src; src = src->next) { - ++count[i]; - if (i < IPHASH_TABLE_SIZE) { - /* don't count the slop buckets in the total */ - ++total; - } - } - } - qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare); - p = buf + apr_snprintf(buf, sizeof(buf), - "iphash: total hashed = %u, avg chain = %u, " - "chain lengths (count x len):", - total, total / IPHASH_TABLE_SIZE); - total = 1; - for (i = 1; i < IPHASH_TABLE_SIZE; ++i) { - if (count[i - 1] != count[i]) { - p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u", - total, count[i - 1]); - total = 1; - } - else { - ++total; - } - } - p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u", - total, count[IPHASH_TABLE_SIZE - 1]); - ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf); -} -#endif - - -/* This hashing function is designed to get good distribution in the cases - * where the server is handling entire "networks" of servers. i.e. a - * whack of /24s. This is probably the most common configuration for - * ISPs with large virtual servers. - * - * NOTE: This function is symmetric (i.e. collapses all 4 octets - * into one), so machine byte order (big/little endianness) does not matter. - * - * Hash function provided by David Hankins. - */ -static APR_INLINE unsigned hash_inaddr(unsigned key) -{ - key ^= (key >> 16); - return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE; -} - -static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa) -{ - unsigned key; - - /* The key is the last four bytes of the IP address. - * For IPv4, this is the entire address, as always. - * For IPv6, this is usually part of the MAC address. - */ - key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4); - return hash_inaddr(key); -} - -static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p, - server_rec *s, server_addr_rec *sar) -{ - ipaddr_chain *new; - - new = apr_palloc(p, sizeof(*new)); - new->names = NULL; - new->server = s; - new->sar = sar; - new->next = NULL; - return new; -} - - -static name_chain *new_name_chain(apr_pool_t *p, - server_rec *s, server_addr_rec *sar) -{ - name_chain *new; - - new = apr_palloc(p, sizeof(*new)); - new->server = s; - new->sar = sar; - new->next = NULL; - return new; -} - - -static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa) -{ - unsigned bucket; - ipaddr_chain *trav; - - /* scan the hash apr_table_t for an exact match first */ - bucket = hash_addr(sa); - for (trav = iphash_table[bucket]; trav; trav = trav->next) { - server_addr_rec *sar = trav->sar; - apr_sockaddr_t *cur = sar->host_addr; - - if (cur->port == 0 || sa->port == 0 || cur->port == sa->port) { - if (apr_sockaddr_equal(cur, sa)) { - return trav; - } - } - } - return NULL; -} - -static ipaddr_chain *find_default_server(apr_port_t port) -{ - server_addr_rec *sar; - ipaddr_chain *trav; - - for (trav = default_list; trav; trav = trav->next) { - sar = trav->sar; - if (sar->host_port == 0 || sar->host_port == port) { - /* match! */ - return trav; - } - } - return NULL; -} - -static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic) -{ - name_chain *nc; - int len; - char buf[MAX_STRING_LEN]; - apr_sockaddr_t *ha = ic->sar->host_addr; - - if (ha->family == APR_INET && - ha->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) { - len = apr_snprintf(buf, sizeof(buf), "_default_:%u", - ic->sar->host_port); - } - else if (ha->family == APR_INET && - ha->sa.sin.sin_addr.s_addr == INADDR_ANY) { - len = apr_snprintf(buf, sizeof(buf), "*:%u", - ic->sar->host_port); - } - else { - len = apr_snprintf(buf, sizeof(buf), "%pI", ha); - } - if (ic->sar->host_port == 0) { - buf[len-1] = '*'; - } - if (ic->names == NULL) { - apr_file_printf(f, "%-22s %s (%s:%u)\n", buf, - ic->server->server_hostname, - ic->server->defn_name, ic->server->defn_line_number); - return; - } - apr_file_printf(f, "%-22s is a NameVirtualHost\n" - "%8s default server %s (%s:%u)\n", - buf, "", ic->server->server_hostname, - ic->server->defn_name, ic->server->defn_line_number); - for (nc = ic->names; nc; nc = nc->next) { - if (nc->sar->host_port) { - apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port); - } - else { - apr_file_printf(f, "%8s port * ", ""); - } - apr_file_printf(f, "namevhost %s (%s:%u)\n", - nc->server->server_hostname, - nc->server->defn_name, nc->server->defn_line_number); - } -} - -static void dump_vhost_config(apr_file_t *f) -{ - ipaddr_chain *ic; - int i; - - apr_file_printf(f, "VirtualHost configuration:\n"); - for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { - for (ic = iphash_table[i]; ic; ic = ic->next) { - dump_a_vhost(f, ic); - } - } - if (default_list) { - apr_file_printf(f, "wildcard NameVirtualHosts and _default_ servers:\n"); - for (ic = default_list; ic; ic = ic->next) { - dump_a_vhost(f, ic); - } - } -} - -/* - * Two helper functions for ap_fini_vhost_config() - */ -static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s, - server_rec *s, server_addr_rec *sar, - ipaddr_chain *ic) -{ - /* the first time we encounter a NameVirtualHost address - * ic->server will be NULL, on subsequent encounters - * ic->names will be non-NULL. - */ - if (ic->names || ic->server == NULL) { - name_chain *nc = new_name_chain(p, s, sar); - nc->next = ic->names; - ic->names = nc; - ic->server = s; - if (sar->host_port != ic->sar->host_port) { - /* one of the two is a * port, the other isn't */ - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_s, - "VirtualHost %s:%u -- mixing * " - "ports and non-* ports with " - "a NameVirtualHost address is not supported," - " proceeding with undefined results", - sar->virthost, sar->host_port); - } - return 1; - } - else { - /* IP-based vhosts are handled by the caller */ - return 0; - } -} - -static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic) -{ - while (*pic) { - ipaddr_chain *ic = *pic; - - if (ic->server == NULL) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_s, - "NameVirtualHost %s:%u has no VirtualHosts", - ic->sar->virthost, ic->sar->host_port); - *pic = ic->next; - } - else if (ic->names == NULL) { - /* if server != NULL and names == NULL then we're done - * looking at NameVirtualHosts - */ - break; - } - else { - pic = &ic->next; - } - } -} - -/* compile the tables and such we need to do the run-time vhost lookups */ -AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s) -{ - server_addr_rec *sar; - int has_default_vhost_addr; - server_rec *s; - int i; - ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE]; - - /* terminate the name_vhost list */ - *name_vhost_list_tail = NULL; - - /* Main host first */ - s = main_s; - - if (!s->server_hostname) { - s->server_hostname = ap_get_local_host(p); - } - - /* initialize the tails */ - for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { - iphash_table_tail[i] = &iphash_table[i]; - } - - /* The first things to go into the hash apr_table_t are the NameVirtualHosts - * Since name_vhost_list is in the same order that the directives - * occured in the config file, we'll copy it in that order. - */ - for (sar = name_vhost_list; sar; sar = sar->next) { - char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */ - unsigned bucket = hash_addr(sar->host_addr); - ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar); - - if (memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, - sar->host_addr->ipaddr_len)) { /* not IN[6]ADDR_ANY */ - *iphash_table_tail[bucket] = ic; - iphash_table_tail[bucket] = &ic->next; - } - else { - /* A wildcard NameVirtualHost goes on the default_list so - * that it can catch incoming requests on any address. - */ - ic->next = default_list; - default_list = ic; - } - /* Notice that what we've done is insert an ipaddr_chain with - * both server and names NULL. This fact is used to spot name- - * based vhosts in add_name_vhost_config(). - */ - } - - /* The next things to go into the hash apr_table_t are the virtual hosts - * themselves. They're listed off of main_s->next in the reverse - * order they occured in the config file, so we insert them at - * the iphash_table_tail but don't advance the tail. - */ - - for (s = main_s->next; s; s = s->next) { - has_default_vhost_addr = 0; - for (sar = s->addrs; sar; sar = sar->next) { - ipaddr_chain *ic; - char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */ - - if ((sar->host_addr->family == AF_INET && - sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) - || !memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) { - ic = find_default_server(sar->host_port); - if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) { - if (ic && ic->sar->host_port != 0) { - ap_log_error(APLOG_MARK, APLOG_WARNING, - 0, main_s, "_default_ VirtualHost " - "overlap on port %u, the first has " - "precedence", sar->host_port); - } - ic = new_ipaddr_chain(p, s, sar); - ic->next = default_list; - default_list = ic; - } - has_default_vhost_addr = 1; - } - else { - /* see if it matches something we've already got */ - ic = find_ipaddr(sar->host_addr); - - if (!ic) { - unsigned bucket = hash_addr(sar->host_addr); - - ic = new_ipaddr_chain(p, s, sar); - ic->next = *iphash_table_tail[bucket]; - *iphash_table_tail[bucket] = ic; - } - else if (!add_name_vhost_config(p, main_s, s, sar, ic)) { - ap_log_error(APLOG_MARK, APLOG_WARNING, - 0, main_s, "VirtualHost %s:%u overlaps " - "with VirtualHost %s:%u, the first has " - "precedence, perhaps you need a " - "NameVirtualHost directive", - sar->virthost, sar->host_port, - ic->sar->virthost, ic->sar->host_port); - ic->sar = sar; - ic->server = s; - } - } - } - - /* Ok now we want to set up a server_hostname if the user was - * silly enough to forget one. - * XXX: This is silly we should just crash and burn. - */ - if (!s->server_hostname) { - if (has_default_vhost_addr) { - s->server_hostname = main_s->server_hostname; - } - else if (!s->addrs) { - /* what else can we do? at this point this vhost has - no configured name, probably because they used - DNS in the VirtualHost statement. It's disabled - anyhow by the host matching code. -djg */ - s->server_hostname = - apr_pstrdup(p, "bogus_host_without_forward_dns"); - } - else { - apr_status_t rv; - char *hostname; - - rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0); - if (rv == APR_SUCCESS) { - s->server_hostname = apr_pstrdup(p, hostname); - } - else { - /* again, what can we do? They didn't specify a - ServerName, and their DNS isn't working. -djg */ - char *ipaddr_str; - - apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr); - ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s, - "Failed to resolve server name " - "for %s (check DNS) -- or specify an explicit " - "ServerName", - ipaddr_str); - s->server_hostname = - apr_pstrdup(p, "bogus_host_without_reverse_dns"); - } - } - } - } - - /* now go through and delete any NameVirtualHosts that didn't have any - * hosts associated with them. Lamers. - */ - for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { - remove_unused_name_vhosts(main_s, &iphash_table[i]); - } - remove_unused_name_vhosts(main_s, &default_list); - -#ifdef IPHASH_STATISTICS - dump_iphash_statistics(main_s); -#endif - if (ap_exists_config_define("DUMP_VHOSTS")) { - apr_file_t *thefile = NULL; - apr_file_open_stderr(&thefile, p); - dump_vhost_config(thefile); - } -} - - -/***************************************************************************** - * run-time vhost matching functions - */ - -/* Lowercase and remove any trailing dot and/or :port from the hostname, - * and check that it is sane. - * - * In most configurations the exact syntax of the hostname isn't - * important so strict sanity checking isn't necessary. However, in - * mass hosting setups (using mod_vhost_alias or mod_rewrite) where - * the hostname is interpolated into the filename, we need to be sure - * that the interpolation doesn't expose parts of the filesystem. - * We don't do strict RFC 952 / RFC 1123 syntax checking in order - * to support iDNS and people who erroneously use underscores. - * Instead we just check for filesystem metacharacters: directory - * separators / and \ and sequences of more than one dot. - */ -static void fix_hostname(request_rec *r) -{ - char *host, *scope_id; - char *dst; - apr_port_t port; - apr_status_t rv; - - /* According to RFC 2616, Host header field CAN be blank. */ - if (!*r->hostname) { - return; - } - - rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); - if (rv != APR_SUCCESS || scope_id) { - goto bad; - } - - if (!host && port) { - /* silly looking host ("Host: 123") but that isn't our job - * here to judge; apr_parse_addr_port() would think we had a port - * but no address - */ - host = apr_itoa(r->pool, (int)port); - } - else if (port) { - /* Don't throw the Host: header's port number away: - save it in parsed_uri -- ap_get_server_port() needs it! */ - /* @@@ XXX there should be a better way to pass the port. - * Like r->hostname, there should be a r->portno - */ - r->parsed_uri.port = port; - r->parsed_uri.port_str = apr_itoa(r->pool, (int)port); - } - - /* if the hostname is an IPv6 numeric address string, it was validated - * already; otherwise, further validation is needed - */ - if (r->hostname[0] != '[') { - for (dst = host; *dst; dst++) { - if (apr_islower(*dst)) { - /* leave char unchanged */ - } - else if (*dst == '.') { - if (*(dst + 1) == '.') { - goto bad; - } - } - else if (apr_isupper(*dst)) { - *dst = apr_tolower(*dst); - } - else if (*dst == '/' || *dst == '\\') { - goto bad; - } - } - /* strip trailing gubbins */ - if (dst > host && dst[-1] == '.') { - dst[-1] = '\0'; - } - } - r->hostname = host; - return; - -bad: - r->status = HTTP_BAD_REQUEST; - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Client sent malformed Host header"); - return; -} - - -/* return 1 if host matches ServerName or ServerAliases */ -static int matches_aliases(server_rec *s, const char *host) -{ - int i; - apr_array_header_t *names; - - /* match ServerName */ - if (!strcasecmp(host, s->server_hostname)) { - return 1; - } - - /* search all the aliases from ServerAlias directive */ - names = s->names; - if (names) { - char **name = (char **) names->elts; - for (i = 0; i < names->nelts; ++i) { - if(!name[i]) continue; - if (!strcasecmp(host, name[i])) - return 1; - } - } - names = s->wild_names; - if (names) { - char **name = (char **) names->elts; - for (i = 0; i < names->nelts; ++i) { - if(!name[i]) continue; - if (!ap_strcasecmp_match(host, name[i])) - return 1; - } - } - return 0; -} - - -/* Suppose a request came in on the same socket as this r, and included - * a header "Host: host:port", would it map to r->server? It's more - * than just that though. When we do the normal matches for each request - * we don't even bother considering Host: etc on non-namevirtualhosts, - * we just call it a match. But here we require the host:port to match - * the ServerName and/or ServerAliases. - */ -AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host, - apr_port_t port) -{ - server_rec *s; - server_addr_rec *sar; - - s = r->server; - - /* search all the <VirtualHost> values */ - /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing - * consider: - * - * NameVirtualHost 10.1.1.1 - * <VirtualHost 10.1.1.1> - * ServerName v1 - * </VirtualHost> - * <VirtualHost 10.1.1.1> - * ServerName v2 - * </VirtualHost> - * - * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say - * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1 - * it would really go to v1. - */ - for (sar = s->addrs; sar; sar = sar->next) { - if ((sar->host_port == 0 || port == sar->host_port) - && !strcasecmp(host, sar->virthost)) { - return 1; - } - } - - /* the Port has to match now, because the rest don't have ports associated - * with them. */ - if (port != s->port) { - return 0; - } - - return matches_aliases(s, host); -} - - -static void check_hostalias(request_rec *r) -{ - /* - * Even if the request has a Host: header containing a port we ignore - * that port. We always use the physical port of the socket. There - * are a few reasons for this: - * - * - the default of 80 or 443 for SSL is easier to handle this way - * - there is less of a possibility of a security problem - * - it simplifies the data structure - * - the client may have no idea that a proxy somewhere along the way - * translated the request to another ip:port - * - except for the addresses from the VirtualHost line, none of the other - * names we'll match have ports associated with them - */ - const char *host = r->hostname; - apr_port_t port; - server_rec *s; - server_rec *last_s; - name_chain *src; - - last_s = NULL; - - apr_sockaddr_port_get(&port, r->connection->local_addr); - - /* Recall that the name_chain is a list of server_addr_recs, some of - * whose ports may not match. Also each server may appear more than - * once in the chain -- specifically, it will appear once for each - * address from its VirtualHost line which matched. We only want to - * do the full ServerName/ServerAlias comparisons once for each - * server, fortunately we know that all the VirtualHost addresses for - * a single server are adjacent to each other. - */ - - for (src = r->connection->vhost_lookup_data; src; src = src->next) { - server_addr_rec *sar; - - /* We only consider addresses on the name_chain which have a matching - * port - */ - sar = src->sar; - if (sar->host_port != 0 && port != sar->host_port) { - continue; - } - - s = src->server; - - /* does it match the virthost from the sar? */ - if (!strcasecmp(host, sar->virthost)) { - goto found; - } - - if (s == last_s) { - /* we've already done ServerName and ServerAlias checks for this - * vhost - */ - continue; - } - last_s = s; - - if (matches_aliases(s, host)) { - goto found; - } - } - return; - -found: - /* s is the first matching server, we're done */ - r->server = s; -} - - -static void check_serverpath(request_rec *r) -{ - server_rec *s; - server_rec *last_s; - name_chain *src; - apr_port_t port; - - apr_sockaddr_port_get(&port, r->connection->local_addr); - - /* - * This is in conjunction with the ServerPath code in http_core, so we - * get the right host attached to a non- Host-sending request. - * - * See the comment in check_hostalias about how each vhost can be - * listed multiple times. - */ - - last_s = NULL; - for (src = r->connection->vhost_lookup_data; src; src = src->next) { - /* We only consider addresses on the name_chain which have a matching - * port - */ - if (src->sar->host_port != 0 && port != src->sar->host_port) { - continue; - } - - s = src->server; - if (s == last_s) { - continue; - } - last_s = s; - - if (s->path && !strncmp(r->uri, s->path, s->pathlen) && - (s->path[s->pathlen - 1] == '/' || - r->uri[s->pathlen] == '/' || - r->uri[s->pathlen] == '\0')) { - r->server = s; - return; - } - } -} - - -AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r) -{ - /* must set this for HTTP/1.1 support */ - if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) { - fix_hostname(r); - if (r->status != HTTP_OK) - return; - } - /* check if we tucked away a name_chain */ - if (r->connection->vhost_lookup_data) { - if (r->hostname) - check_hostalias(r); - else - check_serverpath(r); - } -} - - -/** - * For every virtual host on this connection, call func_cb. - */ -AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn, - ap_vhost_iterate_conn_cb func_cb, - void* baton) -{ - server_rec *s; - server_rec *last_s; - name_chain *src; - apr_port_t port; - int rv = 0; - - if (conn->vhost_lookup_data) { - last_s = NULL; - port = conn->local_addr->port; - - for (src = conn->vhost_lookup_data; src; src = src->next) { - server_addr_rec *sar; - - /* We only consider addresses on the name_chain which have a - * matching port. - */ - sar = src->sar; - if (sar->host_port != 0 && port != sar->host_port) { - continue; - } - - s = src->server; - - if (s == last_s) { - /* we've already done a callback for this vhost. */ - continue; - } - - last_s = s; - - rv = func_cb(baton, conn, s); - - if (rv != 0) { - break; - } - } - } - else { - rv = func_cb(baton, conn, conn->base_server); - } - - return rv; -} - -/* Called for a new connection which has a known local_addr. Note that the - * new connection is assumed to have conn->server == main server. - */ -AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn) -{ - ipaddr_chain *trav; - apr_port_t port; - - /* scan the hash apr_table_t for an exact match first */ - trav = find_ipaddr(conn->local_addr); - - if (trav) { - /* save the name_chain for later in case this is a name-vhost */ - conn->vhost_lookup_data = trav->names; - conn->base_server = trav->server; - return; - } - - /* maybe there's a default server or wildcard name-based vhost - * matching this port - */ - apr_sockaddr_port_get(&port, conn->local_addr); - - trav = find_default_server(port); - if (trav) { - conn->vhost_lookup_data = trav->names; - conn->base_server = trav->server; - return; - } - - /* otherwise we're stuck with just the main server - * and no name-based vhosts - */ - conn->vhost_lookup_data = NULL; -} diff --git a/rubbos/app/httpd-2.0.64/server/vhost.lo b/rubbos/app/httpd-2.0.64/server/vhost.lo deleted file mode 100644 index 506c9cc6..00000000 --- a/rubbos/app/httpd-2.0.64/server/vhost.lo +++ /dev/null @@ -1,12 +0,0 @@ -# vhost.lo - a libtool object file -# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18) -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/vhost.o' - -# Name of the non-PIC object. -non_pic_object='vhost.o' - diff --git a/rubbos/app/httpd-2.0.64/server/vhost.o b/rubbos/app/httpd-2.0.64/server/vhost.o Binary files differdeleted file mode 100644 index 7e23e87a..00000000 --- a/rubbos/app/httpd-2.0.64/server/vhost.o +++ /dev/null |