diff -urN apache_1.3.29/Makefile.tmpl apache-1.3.29-2/Makefile.tmpl
--- apache_1.3.29/Makefile.tmpl	2003-04-28 15:32:12.000000000 +0200
+++ apache-1.3.29-2/Makefile.tmpl	2003-12-10 02:08:08.000000000 +0100
@@ -304,19 +304,20 @@
 		$(INSTALL_PROGRAM) $(TOP)/$(SRC)/$(TARGET) $(root)$(sbindir)/$(TARGET); \
 	fi
 	-@if [ ".`grep 'SUBTARGET=target_shared' $(TOP)/$(SRC)/Makefile`" != . ]; then \
+		SHLIB_PREFIX_NAME="`grep '^SHLIB_PREFIX_NAME=' $(TOP)/$(SRC)/Makefile | sed -e 's:^.*=::'`"; \
 		SHLIB_SUFFIX_NAME="`grep '^SHLIB_SUFFIX_NAME=' $(TOP)/$(SRC)/Makefile | sed -e 's:^.*=::'`"; \
 		SHLIB_SUFFIX_LIST="`grep '^SHLIB_SUFFIX_LIST=' $(TOP)/$(SRC)/Makefile | sed -e 's:^.*=::'`"; \
-		echo "$(INSTALL_CORE) $(TOP)/$(SRC)/lib$(TARGET).ep $(root)$(libexecdir)/lib$(TARGET).ep"; \
-		$(INSTALL_CORE) $(TOP)/$(SRC)/lib$(TARGET).ep $(root)$(libexecdir)/lib$(TARGET).ep; \
-		echo "$(INSTALL_DSO) $(TOP)/$(SRC)/lib$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}"; \
-		$(INSTALL_DSO) $(TOP)/$(SRC)/lib$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}; \
+		echo "$(INSTALL_CORE) $(TOP)/$(SRC)/$${SHLIB_PREFIX_NAME}$(TARGET).ep $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).ep"; \
+		$(INSTALL_CORE) $(TOP)/$(SRC)/$${SHLIB_PREFIX_NAME}$(TARGET).ep $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).ep; \
+		echo "$(INSTALL_DSO) $(TOP)/$(SRC)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME}"; \
+		$(INSTALL_DSO) $(TOP)/$(SRC)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME}; \
 		if [ ".$${SHLIB_SUFFIX_LIST}" != . ]; then \
-			echo "$(RM) $(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}.*"; \
-			$(RM) $(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}.*; \
+			echo "$(RM) $(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME}.*"; \
+			$(RM) $(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME}.*; \
 			for suffix in $${SHLIB_SUFFIX_LIST} ""; do \
 				[ ".$${suffix}" = . ] && continue; \
-				echo "$(LN) $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}.$${suffix}"; \
-				$(LN) $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}.$${suffix}; \
+				echo "$(LN) $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME}.$${suffix}"; \
+				$(LN) $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/$${SHLIB_PREFIX_NAME}$(TARGET).$${SHLIB_SUFFIX_NAME}.$${suffix}; \
 			done; \
 		fi; \
 	fi
diff -urN apache_1.3.29/config.layout apache-1.3.29-2/config.layout
--- apache_1.3.29/config.layout	2002-05-16 18:32:31.000000000 +0200
+++ apache-1.3.29-2/config.layout	2004-01-21 16:56:22.000000000 +0100
@@ -290,7 +290,7 @@
     bindir:        $prefix/bin
     sbindir:       $prefix/sbin
     libexecdir:    $prefix/lib/apache
-    mandir:        $prefix/man
+    mandir:        $prefix/share/man
     sysconfdir:    /etc/apache
     datadir:       /var/www
     iconsdir:      $datadir/icons
diff -urN apache_1.3.29/src/ApacheCore.def apache-1.3.29-2/src/ApacheCore.def
--- apache_1.3.29/src/ApacheCore.def	2002-06-18 06:19:46.000000000 +0200
+++ apache-1.3.29-2/src/ApacheCore.def	2003-12-10 01:12:51.000000000 +0100
@@ -447,3 +447,67 @@
         ap_getline @439
         ap_get_chunk_size @440
         ap_escape_logitem @441
+	
+	; EAPI extended symbols
+	; note; no ID's, so these all bind by name rather than ordinal since 
+	; their ordinals would change with symbol changes in the distribution
+	ap_add_config_define
+	ap_global_ctx  DATA
+	ap_ctx_new
+	ap_ctx_get
+	ap_ctx_overlay
+	ap_ctx_set
+	ap_hook_init
+	ap_hook_kill
+	ap_hook_configure
+	ap_hook_register_I
+	ap_hook_unregister_I
+	ap_hook_status
+	ap_hook_use
+	ap_hook_call
+	ap_set_callback_and_alarm
+	ap_acquire_pool
+	ap_make_shared_sub_pool
+	ap_release_pool
+	ap_mm_useable
+	ap_MM_create
+	ap_MM_permission
+	ap_MM_destroy
+	ap_MM_lock
+	ap_MM_unlock
+	ap_MM_malloc
+	ap_MM_realloc
+	ap_MM_free
+	ap_MM_calloc
+	ap_MM_strdup
+	ap_MM_sizeof
+	ap_MM_maxsize
+	ap_MM_available
+	ap_MM_error
+	ap_mm_create
+	ap_mm_permission
+	ap_mm_destroy
+	ap_mm_lock
+	ap_mm_unlock
+	ap_mm_malloc
+	ap_mm_realloc
+	ap_mm_free
+	ap_mm_calloc
+	ap_mm_strdup
+	ap_mm_sizeof
+	ap_mm_maxsize
+	ap_mm_available
+	ap_mm_error
+	ap_mm_display_info
+	ap_mm_core_create
+	ap_mm_core_permission
+	ap_mm_core_delete
+	ap_mm_core_size
+	ap_mm_core_lock
+	ap_mm_core_unlock
+	ap_mm_core_align2page
+	ap_mm_core_align2word
+	ap_mm_lib_error_set
+	ap_mm_lib_error_get
+	ap_mm_lib_version
+
diff -urN apache_1.3.29/src/Configuration.tmpl apache-1.3.29-2/src/Configuration.tmpl
--- apache_1.3.29/src/Configuration.tmpl	2002-01-17 14:20:50.000000000 +0100
+++ apache-1.3.29-2/src/Configuration.tmpl	2003-12-10 01:12:51.000000000 +0100
@@ -68,6 +68,24 @@
 #TARGET=
 
 ################################################################
+# Extended API (EAPI) support:
+#
+# EAPI:
+#   The EAPI rule enables more module hooks, a generic low-level hook
+#   mechanism, a generic context mechanism and shared memory based pools. 
+#
+# EAPI_MM:
+#   Set the EAPI_MM variable to either the directory of a MM Shared Memory
+#   Library source tree or the installation tree of MM. Alternatively you can
+#   also use the value 'SYSTEM' which then indicates that MM is installed
+#   under various system locations. When the MM library files cannot be found
+#   the EAPI still can be built, but without shared memory pool support, of
+#   course.
+
+Rule EAPI=no
+#EAPI_MM=SYSTEM
+
+################################################################
 # Dynamic Shared Object (DSO) support
 #
 # There is experimental support for compiling the Apache core and
diff -urN apache_1.3.29/src/Configure apache-1.3.29-2/src/Configure
--- apache_1.3.29/src/Configure	2003-07-16 22:27:08.000000000 +0200
+++ apache-1.3.29-2/src/Configure	2003-12-10 01:46:21.000000000 +0100
@@ -254,6 +254,7 @@
 DB_LIB="-ldb"
 SHELL="/bin/sh"
 SUBTARGET="target_static"
+SHLIB_PREFIX_NAME="lib"
 SHLIB_SUFFIX_NAME=""
 SHLIB_SUFFIX_LIST=""
 CAT="cat"
@@ -854,7 +855,7 @@
 	OSDIR="os/cygwin"
 	CFLAGS="$CFLAGS -DCYGWIN"
 	DEF_WANTHSREGEX=yes
-	DBM_LIB="-lgdbm"
+	DBM_LIB="-lgdbm_compat -lgdbm"
 	LIBS="$LIBS -lcrypt $DBM_LIB"
 	if [ "x$RULE_CYGWIN_WINSOCK" = "xyes" ]; then 
 	    CFLAGS="$CFLAGS -DCYGWIN_WINSOCK" 
@@ -1442,6 +1443,7 @@
 	    DEF_SHARED_CORE=yes
 	    LDFLAGS_SHLIB="--export-all"
 	    LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB
+	    SHLIB_PREFIX_NAME=cyg
 	    SHLIB_SUFFIX_NAME=dll
 	    SHMOD_SUFFIX_NAME=dll
 	    SHLIB_SUFFIX_DEPTH=0
@@ -1449,8 +1451,8 @@
 	    LD_SHCORE_DEF=''
 	    LD_SHCORE_LIBS="$LIBS"
 	    LIBS_SHLIB='$(EXTRA_LIBS)'
-	    SHARED_CORE_EP='lib$(TARGET).ep'
-	    SHCORE_IMPLIB='lib$(TARGET).dll'
+	    SHARED_CORE_EP='$(SHLIB_PREFIX_NAME)$(TARGET).ep'
+	    SHCORE_IMPLIB='$(SHLIB_PREFIX_NAME)$(TARGET).dll'
 	    OS_MODULE_INCLUDE='$(SRCDIR)/modules/standard/Makefile.Cygwin'
 	    ;;
 	*)
@@ -1892,6 +1894,72 @@
 fi
 
 ####################################################################
+## Extended API (EAPI) support:
+##
+if [ "x$RULE_EAPI" = "x" ]; then
+    RULE_EAPI=`./helpers/CutRule EAPI $file`
+fi
+if [ "x$RULE_EAPI" = "xyes" ]; then
+    echo " + enabling Extended API (EAPI)"
+    CFLAGS="$CFLAGS -DEAPI"
+    #   some vendor compilers are too restrictive
+    #   for our ap_hook and ap_ctx sources.
+    case "$OS:$CC" in
+        *IRIX-32*:*/cc|*IRIX-32*:cc )
+            CFLAGS="$CFLAGS -woff 1048,1110,1164"
+            ;;
+    esac
+    #   MM Shared Memory Library support for EAPI
+    if [ "x$EAPI_MM" = "x" ]; then
+        EAPI_MM=`egrep '^EAPI_MM=' $file | sed -n -e '$p' | awk -F= '{print $2}'`
+    fi
+    if [ "x$EAPI_MM" != "x" ]; then
+        case $EAPI_MM in
+            SYSTEM|/* ) ;;
+            * ) for p in . .. ../..; do
+                    if [ -d "$p/$EAPI_MM" ]; then
+                        EAPI_MM="`echo $p/$EAPI_MM | sed -e 's;/\./;/;g'`" 
+                        break
+                    fi
+                done
+                ;;
+        esac
+        if [ "x$EAPI_MM" = "xSYSTEM" ]; then
+            echo "   using MM library for EAPI: (system-wide)"
+            CFLAGS="$CFLAGS -DEAPI_MM"
+            __INCLUDES="`mm-config --cflags`"
+            if [ "x$__INCLUDES" != "x-I/usr/include" ]; then
+                INCLUDES="$INCLUDES $__INCLUDES"
+            fi
+            LDFLAGS="$LDFLAGS `mm-config --ldflags`"
+            LIBS="$LIBS `mm-config --libs`"
+        else
+            if [ -f "$EAPI_MM/.libs/libmm.a" -a -f "$EAPI_MM/mm.h" ]; then
+                echo "   using MM library: $EAPI_MM (source-tree only)"
+                case $EAPI_MM in
+                    /* ) ;;
+                    *  ) EAPI_MM="\$(SRCDIR)/$EAPI_MM" ;;
+                esac
+                CFLAGS="$CFLAGS -DEAPI_MM"
+                INCLUDES="$INCLUDES -I$EAPI_MM"
+                LDFLAGS="$LDFLAGS -L$EAPI_MM/.libs"
+                LIBS="$LIBS -lmm"
+            elif [ -f "$EAPI_MM/bin/mm-config" ]; then
+                echo "   using MM library: $EAPI_MM (installed)"
+                CFLAGS="$CFLAGS -DEAPI_MM"
+                INCLUDES="$INCLUDES `$EAPI_MM/bin/mm-config --cflags`"
+                LDFLAGS="$LDFLAGS `$EAPI_MM/bin/mm-config --ldflags`"
+                LIBS="$LIBS `$EAPI_MM/bin/mm-config --libs`"
+            else
+                echo "Configure:Error: Cannot find MM library under $EAPI_MM" 1>&2
+                exit 1
+            fi
+        fi
+    fi
+fi
+
+
+####################################################################
 ## Add in the Expat library if needed/wanted.
 ##
 
@@ -2011,6 +2079,7 @@
     echo "LD_SHCORE_DEF=$LD_SHCORE_DEF" >> Makefile.config
     echo "LD_SHCORE_LIBS=$LD_SHCORE_LIBS" >> Makefile.config
     echo "SHARED_CORE_EP=$SHARED_CORE_EP" >> Makefile.config
+    echo "SHLIB_PREFIX_NAME=$SHLIB_PREFIX_NAME" >> Makefile.config
     echo "SHCORE_IMPLIB=$SHCORE_IMPLIB" >> Makefile.config
 fi
 
diff -urN apache_1.3.29/src/Makefile.tmpl apache-1.3.29-2/src/Makefile.tmpl
--- apache_1.3.29/src/Makefile.tmpl	2003-01-14 22:21:41.000000000 +0100
+++ apache-1.3.29-2/src/Makefile.tmpl	2003-12-10 01:29:01.000000000 +0100
@@ -38,25 +38,25 @@
 target_compile_only: subdirs modules.o
 	$(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c
 
-target_shared: $(SHCORE_IMPLIB) $(SHARED_CORE_EP) lib$(TARGET).$(SHLIB_SUFFIX_NAME)
+target_shared: $(SHCORE_IMPLIB) $(SHARED_CORE_EP) $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME)
 	$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \
 	      -o $(TARGET) -DSHARED_CORE_BOOTSTRAP main/http_main.c \
 	      ap/libap.a $(LIBS) $(SHCORE_IMPLIB)
 
-lib$(TARGET).ep: lib$(TARGET).$(SHLIB_SUFFIX_NAME)
+$(SHLIB_PREFIX_NAME)$(TARGET).ep: $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME)
 	$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \
-	      -o lib$(TARGET).ep -DSHARED_CORE_TIESTATIC main/http_main.c \
+	      -o $(SHLIB_PREFIX_NAME)$(TARGET).ep -DSHARED_CORE_TIESTATIC main/http_main.c \
 		  -L. -l$(TARGET) $(LIBS)
 
-lib$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o
+$(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o
 	$(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c
-	$(LD_SHLIB) $(LDFLAGS_SHLIB) -o lib$(TARGET).$(SHLIB_SUFFIX_NAME) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LD_SHCORE_DEF) $(LD_SHCORE_LIBS)
+	$(LD_SHLIB) $(LDFLAGS_SHLIB) -o $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LD_SHCORE_DEF) $(LD_SHCORE_LIBS)
 	@if [ ".$(SHLIB_SUFFIX_LIST)" != . ]; then \
-		rm -f lib$(TARGET).$(SHLIB_SUFFIX_NAME).*; \
+		rm -f $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME).*; \
 		for suffix in $(SHLIB_SUFFIX_LIST) ""; do \
 			[ ".$$suffix" = . ] && continue; \
-		    echo "ln lib$(TARGET).$(SHLIB_SUFFIX_NAME) lib$(TARGET).$(SHLIB_SUFFIX_NAME).$$suffix"; \
-		    ln lib$(TARGET).$(SHLIB_SUFFIX_NAME) lib$(TARGET).$(SHLIB_SUFFIX_NAME).$$suffix; \
+		    echo "ln $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME) $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME).$$suffix"; \
+		    ln $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME) $(SHLIB_PREFIX_NAME)$(TARGET).$(SHLIB_SUFFIX_NAME).$$suffix; \
 		done; \
 	fi
 
@@ -78,7 +78,7 @@
 	echo "<=== $(SDP)support"
 
 clean:
-	-rm -f $(TARGET) lib$(TARGET).* *.o
+	-rm -f $(TARGET) $(SHLIB_PREFIX_NAME)$(TARGET).* *.o
 	@for i in $(SUBDIRS); do \
 		echo "===> $(SDP)$$i"; \
 		( cd $$i && $(MAKE) $(MFLAGS_STATIC) SDP='$(SDP)' OPTIM='$(OPTIM)' $@ ) || exit 1; \
@@ -86,7 +86,7 @@
 	done
 
 distclean:
-	-rm -f $(TARGET) lib$(TARGET).* *.o
+	-rm -f $(TARGET) $(SHLIB_PREFIX_NAME)$(TARGET).* *.o
 	@for i in $(SUBDIRS); do \
 		echo "===> $(SDP)$$i"; \
 		( cd $$i && $(MAKE) $(MFLAGS_STATIC) SDP='$(SDP)' $@ ) || exit 1; \
diff -urN apache_1.3.29/src/README.EAPI apache-1.3.29-2/src/README.EAPI
--- apache_1.3.29/src/README.EAPI	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/README.EAPI	1999-04-14 13:23:35.000000000 +0200
@@ -0,0 +1,340 @@
+
+ Extended API (EAPI)
+ ===================
+
+ What is EAPI
+ ============
+
+ Extended API (EAPI) is a comprehensive API addition which can be _OPTIONALLY_
+ enabled with ``Rule EAPI=yes'' in src/Configuration or ``--enable-rule=EAPI''
+ on the APACI configure command line. This then defines a -DEAPI and this way
+ the EAPI code is compiled into Apache. When this define is not present _NO_
+ EAPI code is compiled into Apache at all, because all(!) EAPI patches are
+ encapsulated in #ifdef EAPI...#endif.
+
+ What is provided by EAPI?
+ =========================
+
+ EAPI's additions to the Apache API fall into the following categories:
+
+    o  Context Attachment Support for Data Structures
+    o  Loosly-coupled Hook Interface for Inter-Module Communication
+    o  Direct and Pool-based Shared Memory Support 
+    o  Additional Apache Module Hooks
+    o  Specialized EAPI Goodies
+
+ They are discussed in details now....
+
+ Context Attachment Support for Data Structures
+ ----------------------------------------------
+
+ Attaching private information to a request_rec, conn_rec, server_rec or even
+ BUFF structure is for a lot of modules the most elegant solution to keep
+ states between API phases without the need for any global variables. That's
+ especially true for modules which operate on lower I/O levels (where no
+ per-module configuration structure is available) or have to deal with various
+ callback functions of third-party libraries (where one need to find the
+ private context which can be hard without global variables).
+
+ The EAPI way to solve this situation is: 
+
+ 1. A generic context library was written which allows one
+    to create a context and later store and retrieve context variables
+    identified by a unique key.
+
+ 2. The Apache kernel was extended to provide contexts for all standard data
+    structures like request_rec, server_rec, conn_rec, BUFF, etc.  This way
+    modules can easily attach information to all these structures with the
+    help of the context API.
+
+ Point 1 is implemented by new src/ap/ap_ctx.c and src/include/ap_ctx.h source
+ files.  Point 2 is implemented by EAPI patches to various src/main/*.c and
+ src/include/*.h files.
+
+ Example:
+ 
+  | /* a module implements on-the-fly compression for
+  |    the buffer code and for this uses a third-party library which 
+  |    don't uses a filedescriptor. Instead a CLIB* is used.  The module has to
+  |    attach this CLIB* to the BUFF in oder to have it available whenever a
+  |    BUFF is used somewhere. */
+  | BUFF *buff;
+  | CLIB *comp;
+  | comp = CLIB_new_from_fd(buff->fd);
+  | ap_ctx_set(buff->ctx, "CLIB", comp);
+  |   :
+  | 
+  | /* later when it deals with a BUFF, it can easily find back the
+  |    CLIB* via the BUFF* */
+  | comp = (CLIB *)ap_ctx_get(buff->ctx, "CLIB");
+  |   :
+ 
+ Possible use cases from practice are:
+  
+  o  attaching third-party structures to Apache structures
+  o  replacing global module variables with clean context variables
+  o  custom attachments for complex modules like mod_php, mod_php, etc.
+  o  companion support for the hook interface (see below)
+  o  etc. pp.
+
+ Loosly-coupled Hook Interface for Inter-Module Communication
+ ------------------------------------------------------------
+
+ Apache is structured into modules which is a nice idea.  With the Dynamic
+ Shared Object (DSO) facility it gets even nicer because then modules are then
+ really stand-alone objects. The drawback is that DSO restricts modules.  The
+ most popular problem is that no inter-module symbol references are allowed.
+ The classical problem: Module A implements some nice functions module B would
+ like to use to avoid reimplementing the wheel. But B cannot call A's
+ functions because this violates both the design idea of stand-alone modules
+ and the DSO restrictions. Additionally a module C could exists which also
+ provides a variant of the functionality of A's function.  Then B should get
+ the variant (either A's or C's) which is best or available at all.
+ 
+ Real Life Example:
+
+ mod_rewrite provides %{XXXX} constructs to lookup variables.  The available
+ variables are (and have to be) hard-coded into mod_rewrite. Now our mod_clib
+ which does on-the-fly compression provides a variable CLIB_FACTOR which gives
+ information about the shrink factor of the compression and a user wants to
+ use this shrink factor to make an URL-rewriting decision (<grin>). No chance
+ without EAPI.  With EAPI it's easy: Inside the if-cascade for the various
+ variables in mod_rewrite one replaces:
+
+  | char *result;
+  | request_rec *r;
+  |    :
+  | if (strcasecmp(var, "...") == 0) {
+  |    :
+  | else if (strcasecmp(var, "SCRIPT_GROUP") == 0) {
+  |     result = ...
+  | }
+  | else {
+  |     if (result == NULL) {
+  |         ...complain...
+  |     }
+  | }
+  |    :
+
+ with
+
+  | char *result;
+  | request_rec *r;
+  |    :
+  | if (strcasecmp(var, "...") == 0) {
+  |    :
+  | else if (strcasecmp(var, "SCRIPT_GROUP") == 0) {
+  |     result = ...
+  | }
+  | else {
+  |     ap_hook_use("ap::lookup_variable",
+  |                 AP_HOOK_SIG4(ptr,ptr,ptr,ctx), 
+  |                 AP_HOOK_DECLINE(NULL),
+  |                 &result, r, var);
+  |     if (result == NULL) {
+  |         ...complain...
+  |     }
+  | }
+  |    :
+
+ What this does is that when XXXX of %{XXXX} isn't known, a hook named
+ ap::lookup_variable is called with the request_rec and the var ("XXX") and
+ the result variable. When no one has registered for this hook, nothing
+ happens. ap_hook_use() immediately returns and nothing was changed. 
+
+ But now let's assume mod_clib is additionally loaded as a DSO. And without
+ changing anything now magically mod_rewrite implements %{CLIB_FACTOR}. How?
+ Look inside mod_clib.c:
+
+  | /* mod_clib registeres for the ap::lookup_variable hook 
+  | inside it's init phase */
+  | CLIB *comp;
+  | ap_hook_register("ap::lookup_variable", 
+  |                  my_lookup_variable, AP_HOOK_CTX(comp));
+  |
+  | /* and implements the my_lookup_variable() function */
+  | char *my_lookup_variable(request_rec *r, char *name, CLIB *comp)
+  | {
+  |     if (strcmp(name, "CLIB_FACTOR") == 0)
+  |         return ap_psrintf(r->pool, "%d", comp->factor);
+  |     return NULL;
+  | }
+
+ What happens? When mod_rewrite calls the ap_hook_use() function internally
+ the hook facility knows that mod_clib has registered for this hook and calls
+ the equivalent of
+
+ |     result = my_lookup_variable(r, var, <comp>);
+
+ where <comp> is the CLIB* context variable mod_clib has registered for
+ itself. Now assume a second module exists which also provides variables and
+ want to allow mod_rewrite to lookup them.  It registers after mod_clib with
+
+ |      ap_hook_register("ap::lookup_variable", 
+ |                        my_lookup_variable2, AP_HOOK_CTX(whatever));
+ | 
+
+ and then the following happens: The hook facility does for mod_rewrite the
+ equivalent of:
+
+ |      result = my_lookup_variable(r, var, <comp>);
+ |      if (result == NULL)
+ |          result = my_lookup_variable2(r, var, <whatever>);
+
+ As you can see the hook functions decline in this example with NULL.  That's
+ the NULL from AP_HOOK_DECLINE(NULL) and can be any value of any type, of
+ course.
+
+ The same idea can be also used by mod_log_config and every other module which
+ wants to lookup a variable inside Apache. Which variables are available
+ depend on the available modules which implement them. And this all works
+ nicely with the DSO facility, because the ap_hook_xxx() API is part of the
+ Apache kernel code. And nothing has to be changed inside Apache when another
+ modules wants to create a new hook, because the mechanism is totally generic.
+
+ So when our module A wants to let other modules to use it's function it just
+ has to configure a hook for this.  Then other modules call this hook. Is
+ module A not there the boolean return value of the hook call will indicate
+ this. When module A is there the function is called.
+
+ Direct and Pool-based Shared Memory Support
+ -------------------------------------------
+
+ Since years it was annoying that Apache's pre-forked process model basically
+ means that every server lives it's own life (= address space) and this way
+ module authors cannot easily spread module configuration or other data
+ accross the processes.  The most elegant solution is to use shared memory
+ segments.  The drawback is that there is no portable API for shared memory
+ handling and there is no convinient memory allocation API for working inside
+ shared memory segments.
+
+ The EAPI way to solve this situation is: 
+
+ 1. A stand-alone and resuable library was written (named MM from "memory
+    mapped" and available from http://www.engelschall.com/sw/mm/) which
+    abstracts the shared memory and memory mutex fiddling into a low-level
+    API.  Internally the shared memory and mutex functionality is implemented
+    in various platform-depended ways: 4.4BSD or POSIX.1 anonymous memory
+    mapping, /dev/zero-based memory mapping, temporary file memory mapping, or
+    SysV IPC shared memory for allocating the shared memory areas and POSIX.1
+    fcntl(2), BSD flock(2) or SysV IPC semaphores for implementing mutual
+    exclusion capabilities.
+
+    Additionally MM provides a high-level malloc()-style API based on this
+    abstracted shared memory low-level API. The idea is just to allocate the
+    requested memory chunks from shared memory segments instead of the heap.
+
+ 2. EAPI now provides an easy method (with the EAPI_MM configuration 
+    variable) to build Apache against this MM library. For this the whole MM
+    API (mm_xxx() functions) is encapsulated in an Apache API subpart
+    (ap_mm_xxx() functions). This way the API is fixed and always present (no
+    #ifdef EAPI stuff in modules!), but useable only when EAPI was used in
+    conjunction with MM. A simple ``EAPI_MM=/path/to/mm ./configure
+    --enable-rule=EAPI ...'' is enough to put MM under the ap_mm_xxx() API.
+    This way modules can use a consistent, powerful and abstracted ap_mm_xxx()
+    API for dealing with shared memory.
+
+ 3. Because inside Apache mostly all memory handling is done via the
+    pool facility, additional support for ``shared memory pools'' is provided.
+    This way modules can use all ap_pxxx() functions in combination with
+    shared memory.
+
+ Point 1 is implemented inside the MM package. Point 2 is implemented by the
+ new src/ap/ap_mm.c and src/include/ap_mm.h source files.  Point 3 is
+ implemented by EAPI patches to src/main/alloc.c and src/include/alloc.h.
+
+ Example:
+
+ | /* inside a module init function (before the forking!)
+ |    for instance a module allocates a structure with a counter
+ |    in a shared memory segment */
+ | pool *p;
+ | pool *sp;
+ | struct mystuff { int cnt } *my;
+ | sp = ap_make_shared_sub_pool(p);
+ | my = (struct mystuff *)ap_palloc(sp, sizeof(struct mystuff));
+ | my->cnt = 0;
+ | 
+ |     :
+ | /* then under request processing time it's changed by one process */
+ | ap_acquire_pool(sp, AP_POOL_RW);
+ | my->cnt++;
+ | ap_release_pool(sp);
+ |     :
+ | 
+ | /* and at the same time read by other processes */
+ | ap_acquire_pool(sp, AP_POOL_RD);
+ | ap_rprintf(r, "The counter is %d\n", my->cnt);
+ | ap_release_pool(sp);
+
+ Possible use cases from practice are:
+
+  o  assembling traffic or other accounting details
+  o  establishing of high-performance inter-process caches
+  o  inter-process wide keeping of session state information
+  o  shared memory support for mod_perl, mod_php, etc.
+  o  etc. pp.
+
+ Additional Apache Module Hooks
+ ------------------------------
+
+ The above three EAPI additions are all very generic facilities.  But there
+ were also specialized things which were missing in Apache (and needed by
+ modules). Mostly additional API phases. EAPI adds the following additional
+ hook pointers to the module structure:
+
+ add_module: 
+     Called from within ap_add_module() right after the module structure
+     was linked into the Apache internal module list.  It is mainly
+     intended to be used to define configuration defines (<IfDefine>)
+     which have to be available directly after a LoadModule/AddModule.
+     Actually this is the earliest possible hook a module can use.  It's
+     especially important for the modules when they use the hook facility.
+
+ remove_module: 
+     Called from within ap_remove_module() right before the module
+     structure is kicked out from the Apache internal module list.
+     Actually this is last possible hook a module can use and exists for
+     consistency with the add_module hook.
+
+ rewrite_command:
+     Called right after a configuration directive line was read and
+     before it is processed. It is mainly intended to be used for
+     rewriting directives in order to provide backward compatibility to
+     old directive variants.
+
+ new_connection:
+     Called from within the internal new_connection() function, right
+     after the conn_rec structure for the new established connection was
+     created and before Apache starts processing the request with
+     ap_read_request().  It is mainly intended to be used to setup/run
+     connection dependent things like sending start headers for
+     on-the-fly compression, etc.
+
+ close_connection:
+     Called from within the Apache dispatching loop just before any
+     ap_bclose() is performed on the socket connection, but a long time
+     before any pool cleanups are done for the connection (which can be
+     too late for some applications).  It is mainly intended to be used
+     to close/finalize connection dependent things like sending end
+     headers for on-the-fly compression, etc.
+
+ Specialized EAPI Goodies
+ ------------------------
+
+ And finally EAPI now uses some of the new functionality to add a few new
+ EAPI-based goodies to mod_rewrite, mod_status and mod_proxy:
+
+ mod_rewrite:
+     The above presented example of lookup hooks is implemented which allows
+     mod_rewrite to lookup arbitrary variables provides by not known modules.
+
+ mod_status:
+     Any module now can register to an EAPI hook of mod_status which
+     allows it to put additional text on the /status webpages.
+
+ mod_proxy:  
+     Some EAPI hooks are provided to allow other modules to control the HTTP
+     client processing inside mod_proxy.  This can be used for a lot of
+     tricks.
+
diff -urN apache_1.3.29/src/ap/Makefile.tmpl apache-1.3.29-2/src/ap/Makefile.tmpl
--- apache_1.3.29/src/ap/Makefile.tmpl	2002-06-18 02:34:35.000000000 +0200
+++ apache-1.3.29-2/src/ap/Makefile.tmpl	2003-12-10 01:12:51.000000000 +0100
@@ -7,7 +7,7 @@
 
 OBJS=ap_cpystrn.o ap_execve.o ap_fnmatch.o ap_getpass.o ap_md5c.o ap_signal.o \
      ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o ap_ebcdic.o \
-     ap_strtol.o
+     ap_strtol.o ap_hook.o ap_ctx.o ap_mm.o
 
 .c.o:
 	$(CC) -c $(INCLUDES) $(CFLAGS) $<
diff -urN apache_1.3.29/src/ap/ap.mak apache-1.3.29-2/src/ap/ap.mak
--- apache_1.3.29/src/ap/ap.mak	2003-05-23 05:39:01.000000000 +0200
+++ apache-1.3.29-2/src/ap/ap.mak	2003-12-10 01:12:51.000000000 +0100
@@ -44,6 +44,9 @@
 	-@erase "$(INTDIR)\ap_cpystrn.obj"
 	-@erase "$(INTDIR)\ap_fnmatch.obj"
 	-@erase "$(INTDIR)\ap_md5c.obj"
+	-@erase "$(INTDIR)\ap_hook.obj"
+	-@erase "$(INTDIR)\ap_ctx.obj"
+	-@erase "$(INTDIR)\ap_mm.obj"
 	-@erase "$(INTDIR)\ap_sha1.obj"
 	-@erase "$(INTDIR)\ap_signal.obj"
 	-@erase "$(INTDIR)\ap_slack.obj"
@@ -99,6 +102,9 @@
 	"$(INTDIR)\ap_cpystrn.obj" \
 	"$(INTDIR)\ap_fnmatch.obj" \
 	"$(INTDIR)\ap_md5c.obj" \
+	"$(INTDIR)\ap_hook.obj" \
+	"$(INTDIR)\ap_ctx.obj" \
+	"$(INTDIR)\ap_mm.obj" \
 	"$(INTDIR)\ap_sha1.obj" \
 	"$(INTDIR)\ap_signal.obj" \
 	"$(INTDIR)\ap_slack.obj" \
@@ -128,6 +134,9 @@
 	-@erase "$(INTDIR)\ap_cpystrn.obj"
 	-@erase "$(INTDIR)\ap_fnmatch.obj"
 	-@erase "$(INTDIR)\ap_md5c.obj"
+	-@erase "$(INTDIR)\ap_hook.obj"
+	-@erase "$(INTDIR)\ap_ctx.obj"
+	-@erase "$(INTDIR)\ap_mm.obj"
 	-@erase "$(INTDIR)\ap_sha1.obj"
 	-@erase "$(INTDIR)\ap_signal.obj"
 	-@erase "$(INTDIR)\ap_slack.obj"
@@ -183,6 +192,9 @@
 	"$(INTDIR)\ap_cpystrn.obj" \
 	"$(INTDIR)\ap_fnmatch.obj" \
 	"$(INTDIR)\ap_md5c.obj" \
+	"$(INTDIR)\ap_hook.obj" \
+	"$(INTDIR)\ap_ctx.obj" \
+	"$(INTDIR)\ap_mm.obj" \
 	"$(INTDIR)\ap_sha1.obj" \
 	"$(INTDIR)\ap_signal.obj" \
 	"$(INTDIR)\ap_slack.obj" \
diff -urN apache_1.3.29/src/ap/ap_ctx.c apache-1.3.29-2/src/ap/ap_ctx.c
--- apache_1.3.29/src/ap/ap_ctx.c	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/ap/ap_ctx.c	1999-12-30 22:02:56.000000000 +0100
@@ -0,0 +1,155 @@
+/* ====================================================================
+ * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+**  Generic Context Interface for Apache
+**  Written by Ralf S. Engelschall <rse@engelschall.com> 
+*/
+
+#ifdef EAPI
+
+#include "httpd.h"
+#include "ap_config.h"
+#include "ap_ctx.h"
+
+API_EXPORT(ap_ctx *) ap_ctx_new(pool *p)
+{
+    ap_ctx *ctx;
+    int i;
+
+    if (p != NULL) {
+        ctx = (ap_ctx *)ap_palloc(p, sizeof(ap_ctx_rec));
+        ctx->cr_pool = p;
+        ctx->cr_entry = (ap_ctx_entry **)
+            ap_palloc(p, sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
+    }
+    else {
+        ctx = (ap_ctx *)malloc(sizeof(ap_ctx_rec));
+        ctx->cr_pool = NULL;
+        ctx->cr_entry = (ap_ctx_entry **)
+            malloc(sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
+    }
+    for (i = 0; i < AP_CTX_MAX_ENTRIES+1; i++) 
+        ctx->cr_entry[i] = NULL;
+    return ctx;
+}
+
+API_EXPORT(void) ap_ctx_set(ap_ctx *ctx, char *key, void *val)
+{
+    int i;
+    ap_ctx_entry *ce;
+
+    ce = NULL;
+    for (i = 0; ctx->cr_entry[i] != NULL; i++) {
+        if (strcmp(ctx->cr_entry[i]->ce_key, key) == 0) {
+            ce = ctx->cr_entry[i];
+            break;
+        }
+    }
+    if (ce == NULL) {
+        if (i == AP_CTX_MAX_ENTRIES)
+            return;
+        if (ctx->cr_pool != NULL) {
+            ce = (ap_ctx_entry *)ap_palloc(ctx->cr_pool, sizeof(ap_ctx_entry));
+            ce->ce_key = ap_pstrdup(ctx->cr_pool, key);
+        }
+        else {
+            ce = (ap_ctx_entry *)malloc(sizeof(ap_ctx_entry));
+            ce->ce_key = strdup(key);
+        }
+        ctx->cr_entry[i] = ce;
+        ctx->cr_entry[i+1] = NULL;
+    }
+    ce->ce_val = val;
+    return;
+}
+
+API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key)
+{
+    int i;
+
+    for (i = 0; ctx->cr_entry[i] != NULL; i++)
+        if (strcmp(ctx->cr_entry[i]->ce_key, key) == 0)
+            return ctx->cr_entry[i]->ce_val;
+    return NULL;
+}
+
+API_EXPORT(ap_ctx *) ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base)
+{
+    ap_ctx *new;
+    int i;
+
+#ifdef POOL_DEBUG
+    if (p != NULL) {
+        if (!ap_pool_is_ancestor(over->cr_pool, p))
+            ap_log_assert("ap_ctx_overlay: overlay's pool is not an ancestor of p", 
+                          __FILE__, __LINE__);
+        if (!ap_pool_is_ancestor(base->cr_pool, p))
+            ap_log_assert("ap_ctx_overlay: base's pool is not an ancestor of p",
+                          __FILE__, __LINE__);
+    }
+#endif
+    if ((new = ap_ctx_new(p)) == NULL)
+        return NULL;
+    memcpy(new->cr_entry, base->cr_entry, 
+           sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
+    for (i = 0; over->cr_entry[i] != NULL; i++)
+        ap_ctx_set(new, over->cr_entry[i]->ce_key, over->cr_entry[i]->ce_val);
+    return new;
+}
+
+#endif /* EAPI */
diff -urN apache_1.3.29/src/ap/ap_hook.c apache-1.3.29-2/src/ap/ap_hook.c
--- apache_1.3.29/src/ap/ap_hook.c	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/ap/ap_hook.c	1999-12-30 22:02:56.000000000 +0100
@@ -0,0 +1,930 @@
+#if 0
+=pod
+#endif
+/* ====================================================================
+ * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+**  Implementation of a Generic Hook Interface for Apache
+**  Written by Ralf S. Engelschall <rse@engelschall.com> 
+**
+**  See POD document at end of ap_hook.h for description.
+**  View it with the command ``pod2man ap_hook.h | nroff -man | more''
+**
+**  Attention: This source file is a little bit tricky.
+**             It's a combination of a C source and an embedded Perl script
+**             (which updates the C source). The purpose of this is to have
+**             both things together at one place. So you can both pass
+**             this file to the C compiler and the Perl interpreter.
+*/
+
+                                      /*
+                                       * Premature optimization is 
+                                       * the root of all evil.
+                                       *       -- D. E. Knuth
+                                       */
+
+#ifdef EAPI
+
+#include "httpd.h"
+#include "http_log.h"
+#include "ap_config.h"
+#include "ap_hook.h"
+
+/* 
+ * the internal hook pool
+ */
+static ap_hook_entry **ap_hook_pool = NULL;
+
+/* 
+ * forward prototypes for internal functions
+ */
+static int            ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf);
+static ap_hook_entry *ap_hook_create(char *hook);
+static ap_hook_entry *ap_hook_find(char *hook);
+static void           ap_hook_destroy(ap_hook_entry *he);
+
+/*
+ * Initialize the hook mechanism
+ */
+API_EXPORT(void) ap_hook_init(void)
+{
+    int i;
+
+    if (ap_hook_pool != NULL)
+        return;
+    ap_hook_pool = (ap_hook_entry **)malloc(sizeof(ap_hook_entry *)
+                                            *(AP_HOOK_MAX_ENTRIES+1));
+    for (i = 0; i < AP_HOOK_MAX_ENTRIES; i++)
+        ap_hook_pool[i] = NULL;
+    return;
+}
+
+/*
+ * Kill the hook mechanism
+ */
+API_EXPORT(void) ap_hook_kill(void)
+{
+    int i;
+
+    if (ap_hook_pool == NULL)
+        return;
+    for (i = 0; ap_hook_pool[i] != NULL; i++)
+        ap_hook_destroy(ap_hook_pool[i]);
+    free(ap_hook_pool);
+    ap_hook_pool = NULL;
+    return;
+}
+    
+/*
+ * Smart creation of a hook (when it exist this is the same as
+ * ap_hook_find, when it doesn't exists it is created)
+ */
+static ap_hook_entry *ap_hook_create(char *hook)
+{
+    int i;
+    ap_hook_entry *he;
+
+    for (i = 0; ap_hook_pool[i] != NULL; i++)
+        if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
+            return ap_hook_pool[i];
+
+    if (i >= AP_HOOK_MAX_ENTRIES)
+        return NULL;
+
+    if ((he = (ap_hook_entry *)malloc(sizeof(ap_hook_entry))) == NULL)
+        return NULL;
+    ap_hook_pool[i] = he;
+
+    he->he_hook          = strdup(hook);
+    he->he_sig           = AP_HOOK_SIG_UNKNOWN;
+    he->he_modeid        = AP_HOOK_MODE_UNKNOWN;
+    he->he_modeval.v_int = 0;
+
+    he->he_func = (ap_hook_func **)malloc(sizeof(ap_hook_func *)
+                                          *(AP_HOOK_MAX_FUNCS+1));
+    if (he->he_func == NULL)
+        return FALSE;
+
+    for (i = 0; i < AP_HOOK_MAX_FUNCS; i++)
+        he->he_func[i] = NULL;
+    return he;
+}
+
+/*
+ * Find a particular hook
+ */
+static ap_hook_entry *ap_hook_find(char *hook)
+{
+    int i;
+
+    for (i = 0; ap_hook_pool[i] != NULL; i++)
+        if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
+            return ap_hook_pool[i];
+    return NULL;
+}
+
+/*
+ * Destroy a particular hook
+ */
+static void ap_hook_destroy(ap_hook_entry *he)
+{
+    int i;
+
+    if (he == NULL)
+        return;
+    free(he->he_hook);
+    for (i = 0; he->he_func[i] != NULL; i++)
+        free(he->he_func[i]);
+    free(he->he_func);
+    free(he);
+    return;
+}
+
+/*
+ * Configure a particular hook, 
+ * i.e. remember its signature and return value mode
+ */
+API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
+{
+    ap_hook_entry *he;
+    va_list ap;
+    int rc;
+
+    va_start(ap, modeid);
+    if ((he = ap_hook_create(hook)) == NULL)
+        rc = FALSE;
+    else {
+        he->he_sig = sig;
+        he->he_modeid = modeid;
+        if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) {
+            if (AP_HOOK_SIG_HAS(sig, RC, char))
+                he->he_modeval.v_char = va_arg(ap, va_type(char));
+            else if (AP_HOOK_SIG_HAS(sig, RC, int))
+                he->he_modeval.v_int = va_arg(ap, va_type(int));
+            else if (AP_HOOK_SIG_HAS(sig, RC, long))
+                he->he_modeval.v_long = va_arg(ap, va_type(long));
+            else if (AP_HOOK_SIG_HAS(sig, RC, float))
+                he->he_modeval.v_float = va_arg(ap, va_type(float));
+            else if (AP_HOOK_SIG_HAS(sig, RC, double))
+                he->he_modeval.v_double = va_arg(ap, va_type(double));
+            else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
+                he->he_modeval.v_ptr = va_arg(ap, va_type(ptr));
+        }
+        rc = TRUE;
+    }
+    va_end(ap);
+    return rc;
+}
+
+/*
+ * Register a function to call for a hook
+ */
+API_EXPORT(int) ap_hook_register_I(char *hook, void *func, void *ctx)
+{
+    int i, j;
+    ap_hook_entry *he;
+    ap_hook_func *hf;
+
+    if ((he = ap_hook_create(hook)) == NULL)
+        return FALSE;
+
+    for (i = 0; he->he_func[i] != NULL; i++)
+        if (he->he_func[i]->hf_ptr == func)
+            return FALSE;
+
+    if (i == AP_HOOK_MAX_FUNCS)
+        return FALSE;
+
+    if ((hf = (ap_hook_func *)malloc(sizeof(ap_hook_func))) == NULL)
+        return FALSE;
+
+    for (j = i; j >= 0; j--)
+        he->he_func[j+1] = he->he_func[j];
+    he->he_func[0] = hf;
+
+    hf->hf_ptr = func;
+    hf->hf_ctx = ctx;
+
+    return TRUE;
+}
+
+/*
+ * Unregister a function to call for a hook
+ */
+API_EXPORT(int) ap_hook_unregister_I(char *hook, void *func)
+{
+    int i, j;
+    ap_hook_entry *he;
+
+    if ((he = ap_hook_find(hook)) == NULL)
+        return FALSE;
+    for (i = 0; he->he_func[i] != NULL; i++) {
+        if (he->he_func[i]->hf_ptr == func) {
+            free(he->he_func[i]);
+            for (j = i; he->he_func[j] != NULL; j++)
+                he->he_func[j] = he->he_func[j+1];
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+/*
+ * Retrieve the status of a particular hook
+ */
+API_EXPORT(ap_hook_state) ap_hook_status(char *hook)
+{
+    ap_hook_entry *he;
+
+    if ((he = ap_hook_find(hook)) == NULL)
+        return AP_HOOK_STATE_NOTEXISTANT;
+    if (   he->he_func[0] != NULL 
+        && he->he_sig != AP_HOOK_SIG_UNKNOWN
+        && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
+        return AP_HOOK_STATE_REGISTERED;
+    if (   he->he_sig != AP_HOOK_SIG_UNKNOWN 
+        && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
+        return AP_HOOK_STATE_CONFIGURED;
+    return AP_HOOK_STATE_ESTABLISHED;
+}
+
+/*
+ * Use a hook, i.e. optional on-the-fly configure it before calling it
+ */
+API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
+{
+    int i;
+    ap_hook_value modeval;
+    ap_hook_entry *he;
+    va_list ap;
+    int rc;
+
+    va_start(ap, modeid);
+
+    if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) {
+        if (AP_HOOK_SIG_HAS(sig, RC, char))
+            modeval.v_char = va_arg(ap, va_type(char));
+        else if (AP_HOOK_SIG_HAS(sig, RC, int))
+            modeval.v_int = va_arg(ap, va_type(int));
+        else if (AP_HOOK_SIG_HAS(sig, RC, long))
+            modeval.v_long = va_arg(ap, va_type(long));
+        else if (AP_HOOK_SIG_HAS(sig, RC, float))
+            modeval.v_float = va_arg(ap, va_type(float));
+        else if (AP_HOOK_SIG_HAS(sig, RC, double))
+            modeval.v_double = va_arg(ap, va_type(double));
+        else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
+            modeval.v_ptr = va_arg(ap, va_type(ptr));
+    }
+
+    if ((he = ap_hook_create(hook)) == NULL)
+        return FALSE;
+
+    if (he->he_sig == AP_HOOK_SIG_UNKNOWN)
+        he->he_sig = sig;
+    if (he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
+        he->he_modeid  = modeid;
+        he->he_modeval = modeval;
+    }
+
+    for (i = 0; he->he_func[i] != NULL; i++)
+        if (ap_hook_call_func(ap, he, he->he_func[i]))
+            break;
+
+    if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
+        rc = TRUE;
+    else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
+        rc = FALSE;
+    else
+        rc = TRUE;
+
+    va_end(ap);
+    return rc;
+}
+
+/*
+ * Call a hook
+ */
+API_EXPORT(int) ap_hook_call(char *hook, ...)
+{
+    int i;
+    ap_hook_entry *he;
+    va_list ap;
+    int rc;
+    
+    va_start(ap, hook);
+
+    if ((he = ap_hook_find(hook)) == NULL) {
+        va_end(ap);
+        return FALSE;
+    }
+    if (   he->he_sig == AP_HOOK_SIG_UNKNOWN
+        || he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
+        va_end(ap);
+        return FALSE;
+    }
+
+    for (i = 0; he->he_func[i] != NULL; i++)
+        if (ap_hook_call_func(ap, he, he->he_func[i]))
+            break;
+
+    if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
+        rc = TRUE;
+    else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
+        rc = FALSE;
+    else
+        rc = TRUE;
+
+    va_end(ap);
+    return rc;
+}
+
+static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf)
+{
+    void *v_rc;
+    ap_hook_value v_tmp;
+    int rc;
+
+    /*
+     * Now we dispatch the various function calls. We support function
+     * signatures with up to 9 types (1 return type, 8 argument types) where
+     * each argument can have 7 different types (ctx, char, int, long, float,
+     * double, ptr), so theoretically there are 9^7 (=4782969) combinations
+     * possible.  But because we don't need all of them, of course, we
+     * implement only the following well chosen subset (duplicates are ok):
+     *
+     * 1. `The basic hook'.
+     *
+     *    void func()
+     *
+     * 2. The standard set of signatures which form all combinations of
+     *    int&ptr based signatures for up to 3 arguments. We provide
+     *    them per default for module authors.
+     *
+     *    int func()
+     *    ptr func()
+     *    int func(int)
+     *    int func(ptr)
+     *    ptr func(int)
+     *    ptr func(ptr)
+     *    int func(int,int)
+     *    int func(int,ptr)
+     *    int func(ptr,int)
+     *    int func(ptr,ptr)
+     *    ptr func(int,int)
+     *    ptr func(int,ptr)
+     *    ptr func(ptr,int)
+     *    ptr func(ptr,ptr)
+     *    int func(int,int,int)
+     *    int func(int,int,ptr)
+     *    int func(int,ptr,int)
+     *    int func(int,ptr,ptr)
+     *    int func(ptr,int,int)
+     *    int func(ptr,int,ptr)
+     *    int func(ptr,ptr,int)
+     *    int func(ptr,ptr,ptr)
+     *    ptr func(int,int,int)
+     *    ptr func(int,int,ptr)
+     *    ptr func(int,ptr,int)
+     *    ptr func(int,ptr,ptr)
+     *    ptr func(ptr,int,int)
+     *    ptr func(ptr,int,ptr)
+     *    ptr func(ptr,ptr,int)
+     *    ptr func(ptr,ptr,ptr)
+     *
+     * 3. Actually currently used hooks.
+     *
+     *    int   func(ptr)                          [2x]
+     *    int   func(ptr,ptr)                      [2x]
+     *    int   func(ptr,ptr,int)                  [5x]
+     *    int   func(ptr,ptr,ptr,int)              [1x]
+     *    int   func(ptr,ptr,ptr,int,ptr)          [1x]
+     *    int   func(ptr,ptr,ptr,ptr,int)          [1x]
+     *    int   func(ptr,ptr,ptr,ptr,int,ptr)      [1x]
+     *    ptr   func(ptr,ptr)                      [3x]
+     *    ptr   func(ptr,ptr,ptr,ptr,ptr)          [1x]
+     *    void  func(ptr)                          [2x]
+     *    void  func(ptr,int,int)                  [1x]
+     *    void  func(ptr,ptr)                      [5x]
+     *    void  func(ptr,ptr,ptr)                  [3x]
+     *    void  func(ptr,ptr,ptr,ptr)              [2x]
+     *
+     * To simplify the programming task we generate the actual dispatch code
+     * for these calls via the embedded Perl script at the end of this source
+     * file. This script parses the above lines and generates the section
+     * below.  So, when you need more signature variants just add them to the
+     * above list and run
+     *
+     *     $ perl ap_hook.c
+     *
+     * This automatically updates the above code.
+     */
+
+    rc = TRUE;
+    v_rc = NULL;
+    if (!AP_HOOK_SIG_HAS(he->he_sig, RC, void)) {
+        if (he->he_modeid == AP_HOOK_MODE_DECLTMP) {
+            /* the return variable is a temporary one */ 
+            if (AP_HOOK_SIG_HAS(he->he_sig, RC, char))
+                v_rc = &v_tmp.v_char;
+            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, int))
+                v_rc = &v_tmp.v_int;
+            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, long))
+                v_rc = &v_tmp.v_long;
+            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, float))
+                v_rc = &v_tmp.v_float;
+            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, double))
+                v_rc = &v_tmp.v_double;
+            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, ptr))
+                v_rc = &v_tmp.v_ptr;
+        }
+        else {
+            /* the return variable is provided by caller */ 
+            v_rc = va_arg(ap, void *);
+        }
+    }
+
+    /* ----BEGIN GENERATED SECTION-------- */
+    if (he->he_sig == AP_HOOK_SIG1(void)) {
+        /* Call: void func() */
+        ((void(*)())(hf->hf_ptr))();
+    }
+    else if (he->he_sig == AP_HOOK_SIG1(int)) {
+        /* Call: int func() */
+        *((int *)v_rc) = ((int(*)())(hf->hf_ptr))();
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG1(ptr)) {
+        /* Call: ptr func() */
+        *((void * *)v_rc) = ((void *(*)())(hf->hf_ptr))();
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG2(int, int)) {
+        /* Call: int func(int) */
+        int   v1 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(int))(hf->hf_ptr))(v1);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG2(int, ptr)) {
+        /* Call: int func(ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(void *))(hf->hf_ptr))(v1);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG2(ptr, int)) {
+        /* Call: ptr func(int) */
+        int   v1 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(int))(hf->hf_ptr))(v1);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG2(ptr, ptr)) {
+        /* Call: ptr func(ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(void *))(hf->hf_ptr))(v1);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(int, int, int)) {
+        /* Call: int func(int,int) */
+        int   v1 = va_arg(ap, va_type(int));
+        int   v2 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(int, int))(hf->hf_ptr))(v1, v2);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(int, int, ptr)) {
+        /* Call: int func(int,ptr) */
+        int   v1 = va_arg(ap, va_type(int));
+        void *v2 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(int, void *))(hf->hf_ptr))(v1, v2);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(int, ptr, int)) {
+        /* Call: int func(ptr,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(void *, int))(hf->hf_ptr))(v1, v2);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(int, ptr, ptr)) {
+        /* Call: int func(ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(void *, void *))(hf->hf_ptr))(v1, v2);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(ptr, int, int)) {
+        /* Call: ptr func(int,int) */
+        int   v1 = va_arg(ap, va_type(int));
+        int   v2 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(int, int))(hf->hf_ptr))(v1, v2);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(ptr, int, ptr)) {
+        /* Call: ptr func(int,ptr) */
+        int   v1 = va_arg(ap, va_type(int));
+        void *v2 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(int, void *))(hf->hf_ptr))(v1, v2);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, int)) {
+        /* Call: ptr func(ptr,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(void *, int))(hf->hf_ptr))(v1, v2);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, ptr)) {
+        /* Call: ptr func(ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(void *, void *))(hf->hf_ptr))(v1, v2);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, int, int, int)) {
+        /* Call: int func(int,int,int) */
+        int   v1 = va_arg(ap, va_type(int));
+        int   v2 = va_arg(ap, va_type(int));
+        int   v3 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, int, int, ptr)) {
+        /* Call: int func(int,int,ptr) */
+        int   v1 = va_arg(ap, va_type(int));
+        int   v2 = va_arg(ap, va_type(int));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, int)) {
+        /* Call: int func(int,ptr,int) */
+        int   v1 = va_arg(ap, va_type(int));
+        void *v2 = va_arg(ap, va_type(ptr));
+        int   v3 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, ptr)) {
+        /* Call: int func(int,ptr,ptr) */
+        int   v1 = va_arg(ap, va_type(int));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, int)) {
+        /* Call: int func(ptr,int,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        int   v3 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, ptr)) {
+        /* Call: int func(ptr,int,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, int)) {
+        /* Call: int func(ptr,ptr,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        int   v3 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, ptr)) {
+        /* Call: int func(ptr,ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, int)) {
+        /* Call: ptr func(int,int,int) */
+        int   v1 = va_arg(ap, va_type(int));
+        int   v2 = va_arg(ap, va_type(int));
+        int   v3 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, ptr)) {
+        /* Call: ptr func(int,int,ptr) */
+        int   v1 = va_arg(ap, va_type(int));
+        int   v2 = va_arg(ap, va_type(int));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, int)) {
+        /* Call: ptr func(int,ptr,int) */
+        int   v1 = va_arg(ap, va_type(int));
+        void *v2 = va_arg(ap, va_type(ptr));
+        int   v3 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, ptr)) {
+        /* Call: ptr func(int,ptr,ptr) */
+        int   v1 = va_arg(ap, va_type(int));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, int)) {
+        /* Call: ptr func(ptr,int,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        int   v3 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, ptr)) {
+        /* Call: ptr func(ptr,int,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, int)) {
+        /* Call: ptr func(ptr,ptr,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        int   v3 = va_arg(ap, va_type(int));
+        *((void * *)v_rc) = ((void *(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, ptr)) {
+        /* Call: ptr func(ptr,ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG5(int, ptr, ptr, ptr, int)) {
+        /* Call: int func(ptr,ptr,ptr,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        int   v4 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, int, ptr)) {
+        /* Call: int func(ptr,ptr,ptr,int,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        int   v4 = va_arg(ap, va_type(int));
+        void *v5 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, ptr, int)) {
+        /* Call: int func(ptr,ptr,ptr,ptr,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        void *v4 = va_arg(ap, va_type(ptr));
+        int   v5 = va_arg(ap, va_type(int));
+        *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4, v5);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG7(int, ptr, ptr, ptr, ptr, int, ptr)) {
+        /* Call: int func(ptr,ptr,ptr,ptr,int,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        void *v4 = va_arg(ap, va_type(ptr));
+        int   v5 = va_arg(ap, va_type(int));
+        void *v6 = va_arg(ap, va_type(ptr));
+        *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5, v6);
+        rc = (*((int *)v_rc) != he->he_modeval.v_int);
+    }
+    else if (he->he_sig == AP_HOOK_SIG6(ptr, ptr, ptr, ptr, ptr, ptr)) {
+        /* Call: ptr func(ptr,ptr,ptr,ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        void *v4 = va_arg(ap, va_type(ptr));
+        void *v5 = va_arg(ap, va_type(ptr));
+        *((void * *)v_rc) = ((void *(*)(void *, void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
+        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+    }
+    else if (he->he_sig == AP_HOOK_SIG2(void, ptr)) {
+        /* Call: void func(ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        ((void(*)(void *))(hf->hf_ptr))(v1);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(void, ptr, int, int)) {
+        /* Call: void func(ptr,int,int) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        int   v2 = va_arg(ap, va_type(int));
+        int   v3 = va_arg(ap, va_type(int));
+        ((void(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
+    }
+    else if (he->he_sig == AP_HOOK_SIG3(void, ptr, ptr)) {
+        /* Call: void func(ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        ((void(*)(void *, void *))(hf->hf_ptr))(v1, v2);
+    }
+    else if (he->he_sig == AP_HOOK_SIG4(void, ptr, ptr, ptr)) {
+        /* Call: void func(ptr,ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        ((void(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+    }
+    else if (he->he_sig == AP_HOOK_SIG5(void, ptr, ptr, ptr, ptr)) {
+        /* Call: void func(ptr,ptr,ptr,ptr) */
+        void *v1 = va_arg(ap, va_type(ptr));
+        void *v2 = va_arg(ap, va_type(ptr));
+        void *v3 = va_arg(ap, va_type(ptr));
+        void *v4 = va_arg(ap, va_type(ptr));
+        ((void(*)(void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4);
+    }
+    /* ----END GENERATED SECTION---------- */
+    else
+        ap_log_assert("hook signature not implemented", __FILE__, __LINE__);
+
+    if (he->he_modeid == AP_HOOK_MODE_ALL)
+        rc = FALSE;
+    else if (he->he_modeid == AP_HOOK_MODE_TOPMOST)
+        rc = TRUE;
+
+    return rc;
+}
+
+#endif /* EAPI */
+
+/*
+=cut
+##
+##  Embedded Perl script for generating the dispatch section
+##
+
+require 5.003;
+use strict;
+
+#   configuration
+my $file  = $0;
+my $begin = '----BEGIN GENERATED SECTION--------';
+my $end   = '----END GENERATED SECTION----------';
+
+#   special command: find used signatures
+if ($ARGV[0] eq 'used') {
+    my @S = `find .. -type f -name "*.c" -print`;
+    my $s;
+    my %T = ();
+    foreach $s (@S) {
+        $s =~ s|\n$||;
+        open(FP, "<$s") || die;
+        my $source = '';
+        $source .= $_ while (<FP>);
+        close(FP);
+        my %seen = ();
+        sub printme {
+            my ($src, $hook, $sig) = @_;
+            return if ($seen{$hook} == 1);
+            $seen{$hook} = 1;
+            my ($rc, $args) = ($sig =~ m|^([^,]+)(.*)$|);
+            $args =~ s|^,||;
+            $src =~ s|^.+/||;
+            my $sig = sprintf("%-6sfunc(%s)", $rc, $args);
+            $T{$sig}++; 
+        }
+        $source =~ s|\("([^"]+)",\s*AP_HOOK_SIG[0-9]\((.+?)\)|&printme($s, $1, $2), ''|sge;
+    }
+    my $t;
+    foreach $t (sort(keys(%T))) {
+        printf("     *    %-40s [%dx]\n", $t, $T{$t});
+    }
+    exit(0);
+}
+
+#   read ourself and keep a backup
+open(FP, "<$file") || die;
+my $source = '';
+$source .= $_ while (<FP>);
+close(FP);
+open(FP, ">$file.bak") || die;
+print FP $source;
+close(FP);
+
+#   now parse the signature lines and update the code
+my $o = '';
+my $next = 0;
+my $line;
+my %seen = ();
+foreach $line (split(/\n/, $source)) {
+    next if (not $line =~ m|\*\s+\S+\s+func\(.*\)|);
+    my ($sig, $rc, $param) = ($line =~ m|\*\s+((\S+)\s+func\((.*?)\))|);
+    $sig =~ s|\s+| |g;
+
+    next if ($seen{$sig} == 1);
+    $seen{$sig} = 1;
+
+    print "Generating code for `$sig'\n";
+
+    my @S = ($rc, split(/[\s,]+/, $param));
+    my @RS = @S;
+    my $i;
+    for ($i = 0; $i <= $#RS; $i++) {
+        $RS[$i] = 'void *' if ($RS[$i] eq 'ptr');
+        $RS[$i] = 'void *' if ($RS[$i] eq 'ctx');
+    }
+
+    $o .= "else " if ($next); $next++;
+    $o .= sprintf("if (he->he_sig == AP_HOOK_SIG%d(%s)) {\n", $#S+1, join(', ',@S));
+    $o .= sprintf("    \/\* Call: %s \*\/\n", $sig);
+    for ($i = 1; $i <= $#S; $i++) {
+        $o .= sprintf("    %-6sv%d = va_arg(ap, va_type(%s));\n", $RS[$i], $i, $S[$i]);
+    }
+    $o .= "    ";
+    $o .= sprintf("*((%s *)v_rc) = ", $RS[0]) if ($S[0] ne 'void');
+    $o .= sprintf("((%s(*)(%s))(hf->hf_ptr))", $RS[0], join(', ', @RS[1..$#RS]));
+    $o .= "(";
+    for ($i = 1; $i <= $#S; $i++) {
+        $o .= "hf->hf_ctx" if ($S[$i] eq 'ctx');
+        $o .= sprintf("v%d", $i) if ($S[$i] ne 'ctx');
+        $o .= ", " if ($i < $#S);
+    }
+    $o .= ");\n";
+    $o .= sprintf("    rc = (*((%s *)v_rc) != he->he_modeval.v_%s);\n", 
+                  $RS[0], $S[0]) if ($S[0] ne 'void');
+    $o .= "}\n";
+}
+
+#   insert the generated code at the target location
+$o =~ s|^|    |mg;
+$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s;
+
+#   and update the source on disk
+print "Updating file `$file'\n";
+open(FP, ">$file") || die;
+print FP $source;
+close(FP);
+
+=pod
+*/
diff -urN apache_1.3.29/src/ap/ap_mm.c apache-1.3.29-2/src/ap/ap_mm.c
--- apache_1.3.29/src/ap/ap_mm.c	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/ap/ap_mm.c	1999-12-30 22:02:56.000000000 +0100
@@ -0,0 +1,178 @@
+/* ====================================================================
+ * Copyright (c) 1999-2000 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ */
+
+/*
+**  ap_mm.c -- wrapper for MM shared memory library
+**
+**  This file has two reason:
+**
+**  1. Under DSO context we need stubs inside the Apache core code
+**     to make sure the MM library's code is actually available
+**     to the module DSOs.
+**
+**  2. When the MM library cannot be built on the current platform
+**     still provide dummy stubs so modules using the ap_mm_xxx()
+**     functions can be still built. But modules should use
+**     ap_mm_useable() to find out whether they really can use
+**     the MM stuff.
+*/
+                                       /*
+                                        * "What you see is all you get."
+                                        *     -- Brian Kernighan
+                                        */
+#ifdef EAPI
+
+#include "httpd.h"
+#include "ap_mm.h"
+
+#ifdef EAPI_MM
+#include "mm.h"
+API_EXPORT(int) ap_mm_useable(void) { return TRUE;  }
+#define STUB(val,nul)               { return val;   }
+#define STUB_STMT(stmt)             { stmt; return; }
+#else
+API_EXPORT(int) ap_mm_useable(void) { return FALSE; }
+#define STUB(val,nul)               { return nul;   }
+#define STUB_STMT(stmt)             { return;       }
+#endif
+
+API_EXPORT(int) ap_MM_create(size_t size, char *file) 
+    STUB(MM_create(size, file), FALSE)
+API_EXPORT(int) ap_MM_permission(mode_t mode, uid_t owner, gid_t group) 
+    STUB(MM_permission(mode, owner, group), -1)
+API_EXPORT(void) ap_MM_destroy(void)
+    STUB_STMT(MM_destroy())
+API_EXPORT(int) ap_MM_lock(ap_mm_lock_mode mode)
+    STUB(MM_lock(mode), FALSE)
+API_EXPORT(int) ap_MM_unlock(void)
+    STUB(MM_unlock(), FALSE)
+API_EXPORT(void *) ap_MM_malloc(size_t size)
+    STUB(MM_malloc(size), NULL)
+API_EXPORT(void *) ap_MM_realloc(void *ptr, size_t size)
+    STUB(MM_realloc(ptr, size), NULL)
+API_EXPORT(void) ap_MM_free(void *ptr)
+    STUB_STMT(MM_free(ptr))
+API_EXPORT(void *) ap_MM_calloc(size_t number, size_t size)
+    STUB(MM_calloc(number, size), NULL)
+API_EXPORT(char *) ap_MM_strdup(const char *str)
+    STUB(MM_strdup(str), NULL)
+API_EXPORT(size_t) ap_MM_sizeof(void *ptr)
+    STUB(MM_sizeof(ptr), 0)
+API_EXPORT(size_t) ap_MM_maxsize(void)
+    STUB(MM_maxsize(), 0)
+API_EXPORT(size_t) ap_MM_available(void)
+    STUB(MM_available(), 0)
+API_EXPORT(char *) ap_MM_error(void)
+    STUB(MM_error(), NULL)
+
+API_EXPORT(AP_MM *) ap_mm_create(size_t size, char *file)
+    STUB(mm_create(size, file), NULL)
+API_EXPORT(int) ap_mm_permission(AP_MM *mm, mode_t mode, uid_t owner, gid_t group) 
+    STUB(mm_permission(mm, mode, owner, group), -1)
+API_EXPORT(void) ap_mm_destroy(AP_MM *mm)
+    STUB_STMT(mm_destroy(mm))
+API_EXPORT(int) ap_mm_lock(AP_MM *mm, ap_mm_lock_mode mode)
+    STUB(mm_lock(mm, mode), FALSE)
+API_EXPORT(int) ap_mm_unlock(AP_MM *mm)
+    STUB(mm_unlock(mm), FALSE)
+API_EXPORT(void *) ap_mm_malloc(AP_MM *mm, size_t size)
+    STUB(mm_malloc(mm, size), NULL)
+API_EXPORT(void *) ap_mm_realloc(AP_MM *mm, void *ptr, size_t size)
+    STUB(mm_realloc(mm, ptr, size), NULL)
+API_EXPORT(void) ap_mm_free(AP_MM *mm, void *ptr)
+    STUB_STMT(mm_free(mm, ptr))
+API_EXPORT(void *) ap_mm_calloc(AP_MM *mm, size_t number, size_t size)
+    STUB(mm_calloc(mm, number, size), NULL)
+API_EXPORT(char *) ap_mm_strdup(AP_MM *mm, const char *str)
+    STUB(mm_strdup(mm, str), NULL)
+API_EXPORT(size_t) ap_mm_sizeof(AP_MM *mm, void *ptr)
+    STUB(mm_sizeof(mm, ptr), 0)
+API_EXPORT(size_t) ap_mm_maxsize(void)
+    STUB(mm_maxsize(), 0)
+API_EXPORT(size_t) ap_mm_available(AP_MM *mm)
+    STUB(mm_available(mm), 0)
+API_EXPORT(char *) ap_mm_error(void)
+    STUB(mm_error(), NULL)
+API_EXPORT(void) ap_mm_display_info(AP_MM *mm)
+    STUB_STMT(mm_display_info(mm))
+
+API_EXPORT(void *) ap_mm_core_create(size_t size, char *file)
+    STUB(mm_core_create(size, file), NULL)
+API_EXPORT(int) ap_mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group) 
+    STUB(mm_core_permission(core, mode, owner, group), -1)
+API_EXPORT(void) ap_mm_core_delete(void *core)
+    STUB_STMT(mm_core_delete(core))
+API_EXPORT(size_t) ap_mm_core_size(void *core)
+    STUB(mm_core_size(core), 0)
+API_EXPORT(int) ap_mm_core_lock(void *core, ap_mm_lock_mode mode)
+    STUB(mm_core_lock(core, mode), FALSE)
+API_EXPORT(int) ap_mm_core_unlock(void *core)
+    STUB(mm_core_unlock(core), FALSE)
+API_EXPORT(size_t) ap_mm_core_maxsegsize(void)
+    STUB(mm_core_maxsegsize(), 0)
+API_EXPORT(size_t) ap_mm_core_align2page(size_t size)
+    STUB(mm_core_align2page(size), 0)
+API_EXPORT(size_t) ap_mm_core_align2word(size_t size)
+    STUB(mm_core_align2word(size), 0)
+
+API_EXPORT(void) ap_mm_lib_error_set(unsigned int type, const char *str)
+    STUB_STMT(mm_lib_error_set(type, str))
+API_EXPORT(char *) ap_mm_lib_error_get(void)
+    STUB(mm_lib_error_get(), NULL)
+API_EXPORT(int) ap_mm_lib_version(void)
+    STUB(mm_lib_version(), 0)
+
+#endif /* EAPI */
diff -urN apache_1.3.29/src/helpers/find-dbm-lib apache-1.3.29-2/src/helpers/find-dbm-lib
--- apache_1.3.29/src/helpers/find-dbm-lib	2002-01-22 08:39:15.000000000 +0100
+++ apache-1.3.29-2/src/helpers/find-dbm-lib	2003-12-10 01:34:11.000000000 +0100
@@ -37,8 +37,8 @@
         *-cygwin*)
         # we use the shared DLL version of gdbm if available
         DBM_LIB=""
-        if ./helpers/TestCompile lib gdbm dbm_open; then
-            DBM_LIB="-lgdbm"
+        if ./helpers/TestCompile lib gdbm_compat dbm_open; then
+            DBM_LIB="-lgdbm_compat -lgdbm"
             LIBS="$LIBS $DBM_LIB"
             found_dbm=1
         fi
diff -urN apache_1.3.29/src/helpers/install.sh apache-1.3.29-2/src/helpers/install.sh
--- apache_1.3.29/src/helpers/install.sh	2001-06-12 12:24:53.000000000 +0200
+++ apache-1.3.29-2/src/helpers/install.sh	2003-12-10 01:54:19.000000000 +0100
@@ -89,12 +89,8 @@
 
 #  Check if we need to add an executable extension (such as ".exe") 
 #  on specific OS to src and dst
-if [ -f "$src.exe" ]; then
-  if [ -f "$src" ]; then
-    : # Cygwin [ test ] is too stupid to do [ -f "$src.exe" ] && [ ! -f "$src" ]
-  else
-    ext=".exe"
-  fi
+if [ -f "$src.exe" ] && [ ! -f "$src." ]; then
+  ext=".exe"
 fi
 src="$src$ext"
 dst="$dst$ext"
diff -urN apache_1.3.29/src/include/ap_alloc.h apache-1.3.29-2/src/include/ap_alloc.h
--- apache_1.3.29/src/include/ap_alloc.h	2003-02-03 18:13:17.000000000 +0100
+++ apache-1.3.29-2/src/include/ap_alloc.h	2003-12-10 01:12:51.000000000 +0100
@@ -95,6 +95,15 @@
 API_EXPORT(pool *) ap_init_alloc(void);		/* Set up everything */
 void ap_cleanup_alloc(void);
 API_EXPORT(pool *) ap_make_sub_pool(pool *);	/* All pools are subpools of permanent_pool */
+#if defined(EAPI)
+typedef enum { AP_POOL_RD, AP_POOL_RW } ap_pool_lock_mode;
+int ap_shared_pool_possible(void);
+void ap_init_alloc_shared(int);
+void ap_kill_alloc_shared(void);
+API_EXPORT(pool *) ap_make_shared_sub_pool(pool *);
+API_EXPORT(int) ap_acquire_pool(pool *, ap_pool_lock_mode);
+API_EXPORT(int) ap_release_pool(pool *);
+#endif
 API_EXPORT(void) ap_destroy_pool(pool *);
 
 /* pools have nested lifetimes -- sub_pools are destroyed when the
diff -urN apache_1.3.29/src/include/ap_ctx.h apache-1.3.29-2/src/include/ap_ctx.h
--- apache_1.3.29/src/include/ap_ctx.h	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/include/ap_ctx.h	2001-03-12 21:00:54.000000000 +0100
@@ -0,0 +1,110 @@
+/* ====================================================================
+ * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+**  Generic Context Interface for Apache
+**  Written by Ralf S. Engelschall <rse@engelschall.com> 
+*/
+
+#ifdef EAPI
+
+#ifndef AP_CTX_H
+#define AP_CTX_H
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  !FALSE
+#endif
+
+/*
+ * Internal Context Record Definition
+ */
+
+#define AP_CTX_MAX_ENTRIES 1024
+
+typedef struct {
+    char *ce_key;
+    void *ce_val;
+} ap_ctx_entry;
+
+typedef struct {
+    pool          *cr_pool;
+    ap_ctx_entry **cr_entry;
+} ap_ctx_rec;
+
+typedef ap_ctx_rec ap_ctx;
+
+/*
+ * Some convinience macros for storing _numbers_ 0...n in contexts, i.e.
+ * treating numbers as pointers but keeping track of the NULL return code of
+ * ap_ctx_get.
+ */
+#define AP_CTX_NUM2PTR(n) (void *)(((unsigned long)(n))+1)
+#define AP_CTX_PTR2NUM(p) (unsigned long)(((char *)(p))-1)
+
+/*
+ * Prototypes for Context Handling Functions
+ */
+
+API_EXPORT(ap_ctx *)ap_ctx_new(pool *p);
+API_EXPORT(void)    ap_ctx_set(ap_ctx *ctx, char *key, void *val);
+API_EXPORT(void *)  ap_ctx_get(ap_ctx *ctx, char *key);
+API_EXPORT(ap_ctx *)ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base);
+
+#endif /* AP_CTX_H */
+
+#endif /* EAPI */
diff -urN apache_1.3.29/src/include/ap_hook.h apache-1.3.29-2/src/include/ap_hook.h
--- apache_1.3.29/src/include/ap_hook.h	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/include/ap_hook.h	1999-12-30 22:02:59.000000000 +0100
@@ -0,0 +1,710 @@
+#if 0
+=cut
+#endif
+/* ====================================================================
+ * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+**  Implementation of a Generic Hook Interface for Apache
+**  Written by Ralf S. Engelschall <rse@engelschall.com> 
+**
+**  See POD document at end of this file for description.
+**  View it with the command ``pod2man ap_hook.h | nroff -man | more''
+**
+**  Attention: This header file is a little bit tricky.
+**             It's a combination of a C source and an embedded POD document
+**             The purpose of this is to have both things together at one
+**             place. So you can both pass this file to the C compiler and 
+**             the pod2man translater.
+*/
+
+#ifdef EAPI
+
+#ifndef AP_HOOK_H
+#define AP_HOOK_H
+
+/*
+ * Function Signature Specification:
+ *
+ * We encode the complete signature ingredients as a bitfield
+ * stored in a single unsigned long integer value, which can be
+ * constructed with AP_HOOK_SIGx(...)
+ */
+
+/* the type of the signature bitfield */
+typedef unsigned long int ap_hook_sig;
+
+/* the mask (bin) 111 (hex 0x7) for the triples in the bitfield */
+#define AP_HOOK_SIG_TRIPLE_MASK  0x7
+
+/* the position of the triple */
+#define AP_HOOK_SIG_TRIPLE_POS(n) ((n)*3)
+
+/* the constructor for triple #n with value v */
+#define AP_HOOK_SIG_TRIPLE(n,v) \
+        (((ap_hook_sig)(v))<<((AP_HOOK_##n)*3))
+
+/* the check whether triple #n in sig contains value v */
+#define AP_HOOK_SIG_HAS(sig,n,v) \
+        ((((ap_hook_sig)(sig))&AP_HOOK_SIG_TRIPLE(n, AP_HOOK_SIG_TRIPLE_MASK)) == (AP_HOOK_##n##_##v))
+
+/* utility function to get triple #n in sig */
+#define AP_HOOK_SIG_TRIPLE_GET(sig,n) \
+        ((((ap_hook_sig)(sig))>>AP_HOOK_SIG_TRIPLE_POS(n))&(AP_HOOK_SIG_TRIPLE_MASK))
+
+/* utility function to set triple #n in sig to value v */
+#define AP_HOOK_SIG_TRIPLE_SET(sig,n,v) \
+        ((((ap_hook_sig)(sig))&~(AP_HOOK_SIG_TRIPLE_MASK<<AP_HOOK_SIG_TRIPLE_POS(n)))|((v)<<AP_HOOK_SIG_TRIPLE_POS(n)))
+
+/* define the ingredients for the triple #0: id stuff */
+#define AP_HOOK_ID          0
+#define AP_HOOK_ID_ok       AP_HOOK_SIG_TRIPLE(ID,0)
+#define AP_HOOK_ID_undef    AP_HOOK_SIG_TRIPLE(ID,1)
+
+/* define the ingredients for the triple #1: return code */
+#define AP_HOOK_RC          1
+#define AP_HOOK_RC_void     AP_HOOK_SIG_TRIPLE(RC,0)
+#define AP_HOOK_RC_char     AP_HOOK_SIG_TRIPLE(RC,1)
+#define AP_HOOK_RC_int      AP_HOOK_SIG_TRIPLE(RC,2)
+#define AP_HOOK_RC_long     AP_HOOK_SIG_TRIPLE(RC,3)
+#define AP_HOOK_RC_float    AP_HOOK_SIG_TRIPLE(RC,4)
+#define AP_HOOK_RC_double   AP_HOOK_SIG_TRIPLE(RC,5)
+#define AP_HOOK_RC_ptr      AP_HOOK_SIG_TRIPLE(RC,6)
+
+/* define the ingredients for the triple #2: argument 1 */
+#define AP_HOOK_A1          2
+#define AP_HOOK_A1_ctx      AP_HOOK_SIG_TRIPLE(A1,0)
+#define AP_HOOK_A1_char     AP_HOOK_SIG_TRIPLE(A1,1)
+#define AP_HOOK_A1_int      AP_HOOK_SIG_TRIPLE(A1,2)
+#define AP_HOOK_A1_long     AP_HOOK_SIG_TRIPLE(A1,3)
+#define AP_HOOK_A1_float    AP_HOOK_SIG_TRIPLE(A1,4)
+#define AP_HOOK_A1_double   AP_HOOK_SIG_TRIPLE(A1,5)
+#define AP_HOOK_A1_ptr      AP_HOOK_SIG_TRIPLE(A1,6)
+
+/* define the ingredients for the triple #3: argument 2 */
+#define AP_HOOK_A2          3
+#define AP_HOOK_A2_ctx      AP_HOOK_SIG_TRIPLE(A2,0)
+#define AP_HOOK_A2_char     AP_HOOK_SIG_TRIPLE(A2,1)
+#define AP_HOOK_A2_int      AP_HOOK_SIG_TRIPLE(A2,2)
+#define AP_HOOK_A2_long     AP_HOOK_SIG_TRIPLE(A2,3)
+#define AP_HOOK_A2_float    AP_HOOK_SIG_TRIPLE(A2,4)
+#define AP_HOOK_A2_double   AP_HOOK_SIG_TRIPLE(A2,5)
+#define AP_HOOK_A2_ptr      AP_HOOK_SIG_TRIPLE(A2,6)
+
+/* define the ingredients for the triple #4: argument 3 */
+#define AP_HOOK_A3          4
+#define AP_HOOK_A3_ctx      AP_HOOK_SIG_TRIPLE(A3,0)
+#define AP_HOOK_A3_char     AP_HOOK_SIG_TRIPLE(A3,1)
+#define AP_HOOK_A3_int      AP_HOOK_SIG_TRIPLE(A3,2)
+#define AP_HOOK_A3_long     AP_HOOK_SIG_TRIPLE(A3,3)
+#define AP_HOOK_A3_float    AP_HOOK_SIG_TRIPLE(A3,4)
+#define AP_HOOK_A3_double   AP_HOOK_SIG_TRIPLE(A3,5)
+#define AP_HOOK_A3_ptr      AP_HOOK_SIG_TRIPLE(A3,6)
+
+/* define the ingredients for the triple #5: argument 4 */
+#define AP_HOOK_A4          5
+#define AP_HOOK_A4_ctx      AP_HOOK_SIG_TRIPLE(A4,0)
+#define AP_HOOK_A4_char     AP_HOOK_SIG_TRIPLE(A4,1)
+#define AP_HOOK_A4_int      AP_HOOK_SIG_TRIPLE(A4,2)
+#define AP_HOOK_A4_long     AP_HOOK_SIG_TRIPLE(A4,3)
+#define AP_HOOK_A4_float    AP_HOOK_SIG_TRIPLE(A4,4)
+#define AP_HOOK_A4_double   AP_HOOK_SIG_TRIPLE(A4,5)
+#define AP_HOOK_A4_ptr      AP_HOOK_SIG_TRIPLE(A4,6)
+
+/* define the ingredients for the triple #6: argument 5 */
+#define AP_HOOK_A5          6
+#define AP_HOOK_A5_ctx      AP_HOOK_SIG_TRIPLE(A5,0)
+#define AP_HOOK_A5_char     AP_HOOK_SIG_TRIPLE(A5,1)
+#define AP_HOOK_A5_int      AP_HOOK_SIG_TRIPLE(A5,2)
+#define AP_HOOK_A5_long     AP_HOOK_SIG_TRIPLE(A5,3)
+#define AP_HOOK_A5_float    AP_HOOK_SIG_TRIPLE(A5,4)
+#define AP_HOOK_A5_double   AP_HOOK_SIG_TRIPLE(A5,5)
+#define AP_HOOK_A5_ptr      AP_HOOK_SIG_TRIPLE(A5,6)
+
+/* define the ingredients for the triple #7: argument 6 */
+#define AP_HOOK_A6          7
+#define AP_HOOK_A6_ctx      AP_HOOK_SIG_TRIPLE(A6,0)
+#define AP_HOOK_A6_char     AP_HOOK_SIG_TRIPLE(A6,1)
+#define AP_HOOK_A6_int      AP_HOOK_SIG_TRIPLE(A6,2)
+#define AP_HOOK_A6_long     AP_HOOK_SIG_TRIPLE(A6,3)
+#define AP_HOOK_A6_float    AP_HOOK_SIG_TRIPLE(A6,4)
+#define AP_HOOK_A6_double   AP_HOOK_SIG_TRIPLE(A6,5)
+#define AP_HOOK_A6_ptr      AP_HOOK_SIG_TRIPLE(A6,6)
+
+/* define the ingredients for the triple #8: argument 7 */
+#define AP_HOOK_A7          8
+#define AP_HOOK_A7_ctx      AP_HOOK_SIG_TRIPLE(A7,0)
+#define AP_HOOK_A7_char     AP_HOOK_SIG_TRIPLE(A7,1)
+#define AP_HOOK_A7_int      AP_HOOK_SIG_TRIPLE(A7,2)
+#define AP_HOOK_A7_long     AP_HOOK_SIG_TRIPLE(A7,3)
+#define AP_HOOK_A7_float    AP_HOOK_SIG_TRIPLE(A7,4)
+#define AP_HOOK_A7_double   AP_HOOK_SIG_TRIPLE(A7,5)
+#define AP_HOOK_A7_ptr      AP_HOOK_SIG_TRIPLE(A7,6)
+
+/* define the ingredients for the triple #9: argument 8 */
+#define AP_HOOK_A8          9
+#define AP_HOOK_A8_ctx      AP_HOOK_SIG_TRIPLE(9,0)
+#define AP_HOOK_A8_char     AP_HOOK_SIG_TRIPLE(9,1)
+#define AP_HOOK_A8_int      AP_HOOK_SIG_TRIPLE(9,2)
+#define AP_HOOK_A8_long     AP_HOOK_SIG_TRIPLE(9,3)
+#define AP_HOOK_A8_float    AP_HOOK_SIG_TRIPLE(9,4)
+#define AP_HOOK_A8_double   AP_HOOK_SIG_TRIPLE(9,5)
+#define AP_HOOK_A8_ptr      AP_HOOK_SIG_TRIPLE(9,6)
+  
+/* the constructor for unknown signatures */
+#define AP_HOOK_SIG_UNKNOWN AP_HOOK_ID_undef
+
+/* the constructor for signatures with 1 type */
+#define AP_HOOK_SIG1(rc) \
+        (AP_HOOK_RC_##rc)
+
+/* the constructor for signatures with 2 types */
+#define AP_HOOK_SIG2(rc,a1) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1)
+
+/* the constructor for signatures with 3 types */
+#define AP_HOOK_SIG3(rc,a1,a2) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2)
+
+/* the constructor for signatures with 4 types */
+#define AP_HOOK_SIG4(rc,a1,a2,a3) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3)
+
+/* the constructor for signatures with 5 types */
+#define AP_HOOK_SIG5(rc,a1,a2,a3,a4) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4)
+
+/* the constructor for signatures with 6 types */
+#define AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5)
+
+/* the constructor for signatures with 7 types */
+#define AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5|AP_HOOK_A6_##a6)
+
+/* the constructor for signatures with 8 types */
+#define AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5|AP_HOOK_A6_##a6|AP_HOOK_A7_##a7)
+
+/* the constructor for signatures with 9 types */
+#define AP_HOOK_SIG9(rc,a1,a2,a3,a4,a5,a6,a7,a8) \
+        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5|AP_HOOK_A6_##a6|AP_HOOK_A7_##a7|AP_HOOK_A8_##a8)
+
+/*
+ * Return Value Mode Identification
+ */
+
+/* the type of the return value modes */
+typedef unsigned int ap_hook_mode;
+
+/* the mode of the return value */
+#define AP_HOOK_MODE_UNKNOWN  0
+#define AP_HOOK_MODE_TOPMOST  1
+#define AP_HOOK_MODE_DECLINE  2
+#define AP_HOOK_MODE_DECLTMP  3
+#define AP_HOOK_MODE_ALL      4
+
+/* the constructors for the return value modes */
+#define AP_HOOK_TOPMOST       AP_HOOK_MODE_TOPMOST
+#define AP_HOOK_DECLINE(val)  AP_HOOK_MODE_DECLINE, (val)   
+#define AP_HOOK_DECLTMP(val)  AP_HOOK_MODE_DECLTMP, (val)   
+#define AP_HOOK_ALL           AP_HOOK_MODE_ALL
+
+/*
+ * Hook State Identification
+ */
+
+/* the type of the hook state */
+typedef unsigned short int ap_hook_state;
+
+/* the values of the hook state */
+#define AP_HOOK_STATE_UNDEF       0
+#define AP_HOOK_STATE_NOTEXISTANT 1
+#define AP_HOOK_STATE_ESTABLISHED 2
+#define AP_HOOK_STATE_CONFIGURED  3
+#define AP_HOOK_STATE_REGISTERED  4
+
+/*
+ * Hook Context Identification
+ *
+ * Notice: Null is ok here, because AP_HOOK_NOCTX is just a dummy argument
+ *         because we know from the signature whether the argument is a
+ *         context value or just the dummy value.
+ */
+
+#define AP_HOOK_NOCTX  (void *)(0)
+#define AP_HOOK_CTX(v) (void *)(v)
+
+/*
+ * Internal Hook Record Definition
+ */
+
+/* the union holding the arbitrary decline values */
+typedef union {
+    char   v_char;
+    int    v_int;
+    long   v_long;
+    float  v_float;
+    double v_double;
+    void  *v_ptr;
+} ap_hook_value;
+
+/* the structure holding one hook function and its context */
+typedef struct {
+    void *hf_ptr;              /* function pointer       */
+    void *hf_ctx;              /* function context       */
+} ap_hook_func;
+
+/* the structure holding one hook entry with all its registered functions */
+typedef struct {
+    char          *he_hook;    /* hook name (=unique id) */
+    ap_hook_sig    he_sig;     /* hook signature         */
+    int            he_modeid;  /* hook mode id           */
+    ap_hook_value  he_modeval; /* hook mode value        */
+    ap_hook_func **he_func;    /* hook registered funcs  */
+} ap_hook_entry;
+
+/* the maximum number of hooks and functions per hook */
+#define AP_HOOK_MAX_ENTRIES 512
+#define AP_HOOK_MAX_FUNCS   128
+
+/*
+ * Extended Variable Argument (vararg) Support
+ *
+ * In ANSI C varargs exists, but because the prototypes of function with
+ * varargs cannot reflect the types of the varargs, K&R argument passing
+ * conventions have to apply for the compiler.  This means mainly a conversion
+ * of shorter type variants to the maximum variant (according to sizeof). The
+ * above va_type() macro provides this mapping from the wanted types to the
+ * physically used ones.
+ */
+
+/* the mapping */
+#define VA_TYPE_char   int
+#define VA_TYPE_short  int
+#define VA_TYPE_int    int
+#define VA_TYPE_long   long
+#define VA_TYPE_float  double
+#define VA_TYPE_double double
+#define VA_TYPE_ptr    void *
+#define VA_TYPE_ctx    void *
+
+/* the constructor */
+#ifdef  va_type
+#undef  va_type
+#endif
+#define va_type(type)  VA_TYPE_ ## type
+
+/*
+ * Miscellaneous stuff
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  !FALSE
+#endif
+
+/*
+ * Wrapper macros for the callback-function register/unregister calls.  
+ * 
+ * Background: Strict ANSI C doesn't allow a function pointer to be treated as
+ * a void pointer on argument passing, but we cannot declare the argument as a
+ * function prototype, because the functions can have arbitrary signatures. So
+ * we have to use a void pointer here. But to not require explicit casts on
+ * function pointers for every register/unregister call, we smooth the API a
+ * little bit by providing these macros.
+ */
+
+#define ap_hook_register(hook,func,ctx) ap_hook_register_I(hook,(void *)(func),ctx)
+#define ap_hook_unregister(hook,func)   ap_hook_unregister_I(hook,(void *)(func))
+
+/*
+ * Prototypes for the hook API functions
+ */
+
+API_EXPORT(void)          ap_hook_init         (void);
+API_EXPORT(void)          ap_hook_kill         (void);
+API_EXPORT(int)           ap_hook_configure    (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);
+API_EXPORT(int)           ap_hook_register_I   (char *hook, void *func, void *ctx);
+API_EXPORT(int)           ap_hook_unregister_I (char *hook, void *func);
+API_EXPORT(ap_hook_state) ap_hook_status       (char *hook);
+API_EXPORT(int)           ap_hook_use          (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);
+API_EXPORT(int)           ap_hook_call         (char *hook, ...);
+
+#endif /* AP_HOOK_H */
+
+#endif /* EAPI */
+/*
+=pod
+##
+##  Embedded POD document
+##
+
+=head1 NAME
+
+B<ap_hook> - B<Generic Hook Interface for Apache>
+
+=head1 SYNOPSIS
+
+B<Hook Library Setup:>
+
+ void ap_hook_init(void);
+ void ap_hook_kill(void);
+
+B<Hook Configuration and Registration:>
+
+ int ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode mode);
+ int ap_hook_register(char *hook, void *func, void *ctx);
+ int ap_hook_unregister(char *hook, void *func);
+
+B<Hook Usage:>
+
+ ap_hook_state ap_hook_status(char *hook);
+ int ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode mode, ...);
+ int ap_hook_call(char *hook, ...);
+
+B<Hook Signature Constructors> (ap_hook_sig):
+
+ AP_HOOK_SIG1(rc)
+ AP_HOOK_SIG2(rc,a1)
+ AP_HOOK_SIG3(rc,a1,a2)
+ AP_HOOK_SIG4(rc,a1,a2,a3)
+ AP_HOOK_SIG5(rc,a1,a2,a3,a4)
+ AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5)
+ AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6)
+ AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7)
+
+B<Hook Modes Constructors> (ap_hook_mode):
+
+ AP_HOOK_TOPMOST
+ AP_HOOK_DECLINE(value)
+ AP_HOOK_DECLTMP(value)
+ AP_HOOK_ALL
+
+B<Hook States> (ap_hook_state):
+
+ AP_HOOK_STATE_UNDEF
+ AP_HOOK_STATE_NOTEXISTANT
+ AP_HOOK_STATE_ESTABLISHED
+ AP_HOOK_STATE_CONFIGURED 
+ AP_HOOK_STATE_REGISTERED
+
+=head1 DESCRIPTION
+
+This library implements a generic hook interface for Apache which can be used
+to loosely couple code through arbitrary hooks. There are two use cases for
+this mechanism:
+
+=over 3
+
+=item B<1. Extension and Overrides>
+
+Inside a specific code section you want to perform a specific function call
+for extension reasons.  But you want to allow one or more modules to implement
+this function by registering hooks. Those hooks are registered on a stack and
+can be even configured to have a I<decline> return value. As long as there are
+functions which return the decline value the next function on the stack is
+tried. When the first function doesn't return the decline value the hook call
+stops. 
+
+The original intent of this use case is to provide a flexible extension
+mechanism where modules can override functionality.
+
+=item B<2. Intercommunication>
+
+Inside a specific code you have a function you want to export. But you first
+want to allow other code to override this function.  And second you want to
+export this function without real object file symbol references. Instead you
+want to register the function and let the users call this function by name. 
+
+The original intent of this use case is to allow inter-module communication
+without direct symbol references, which are a big I<no-no> for the I<Dynamic
+Shared Object> (DSO) situation.
+
+=back
+
+And the following design goals existed:
+
+=over 3
+
+=item B<1. Minimum code changes>
+
+The hook calls should look very similar to the corresponding direct function
+call to allow one to easily translate it. And the total amount of changes for
+the hook registration, hook configuration and hook usage should be as small as
+possible to minimize the total code changes. Additionally a shorthand API
+function (ap_hook_use) should be provided which lets one trivially add a hook
+by just changing the code at a single location.
+
+=item B<2. The hook call has to be maximum flexible>
+
+In order to avoid nasty hacks, maximum flexiblity for the hook calls is
+needed, i.e. any function signature (the set of types for the return value and
+the arguments) should be supported.  And it should be possible to
+register always a context (ctx) variable with a function which is passed to
+the corresponding function when the hook call is performed.
+
+=back
+
+The implementation of this library directly followed these two design goals.
+
+=head1 USAGE
+
+Using this hook API is a four-step process:
+
+=over 3
+
+=item B<1. Initialization>
+
+Initialize or destroy the hook mechanism inside your application program:
+
+ ap_hook_init();
+    :
+ ap_hook_kill();
+
+=item B<2. Configuration>
+
+Configure a particular hook by specifing its name, signature and return type
+semantic:
+
+ ap_hook_configure("lookup", AP_HOOK_SIG2(ptr,ptr,ctx), AP_HOOK_DECLINE(NULL));
+ ap_hook_configure("setup", AP_HOOK_SIG2(int,ptr,char), AP_HOOK_DECLTMP(FALSE));
+ ap_hook_configure("read", AP_HOOK_SIG2(void,ptr), AP_HOOK_TOPMOST);
+ ap_hook_configure("logit", AP_HOOK_SIG2(void,ptr), AP_HOOK_ALL);
+
+This configures four hooks: 
+
+A hook named C<lookup> with the signature C<void *lookup(void *, void *)>
+(where the second argument is C<NULL> or the private context pointer of the
+hook function which can be optionally provided at the registration step
+later) and a return code semantic which says: Proceed as long as the
+registered lookup functions return C<NULL> or no more registered functions
+exists. A call for this hook has to provide 2 argument only (a pointer to the
+return variable and the first argument), because the context is
+implicitly provided by the hook mechanism. Sample idea: I<The first function
+who was successful in looking up a variable provides the value>.
+
+A hook named C<setup> with the signature C<int setup(void *, char)" and a
+return code semantic equal to the one of the C<lookup> hook. But the decline
+return value is implemented by a temporay variable of the hook mechanism and
+only used for the decline decision. So a call to this hook has to provide 2
+arguments only (the first and second argument, but no address to a return
+value). Sample idea: I<Any function can handle the setup and when one
+function handled it stops the processing by indicating this with the return
+value>.
+
+A hook named C<read> with the signature C<void read(void *)> and a return code
+semantic which says: Only the top most function on the registered function
+stack is tried (and independet of a possible return value in non-void
+context). A call to this hook has to provide exactly 1 argument (the
+single argument to the hook function). Sample idea: I<We want to
+use a read function and allow others to override it, but independent how much
+registered functions exists, only top most (= last registered) function
+overrides and is used>.
+
+A hook named C<logit> with the signature C<void logit(void *)> and a return
+code semantic which says: All registered functions on the hook functioin stack
+are tried. Sample idea: I<We pass a FILE pointer to the logging functions and
+any function can log whatever it wants>.
+
+=item B<3. Registration>
+
+Register the actual functions which should be used by the hook:
+
+ ap_hook_register("lookup", mylookup, mycontext);
+ ap_hook_register("setup", mysetup);
+ ap_hook_register("read", myread);
+ ap_hook_register("logit", mylogit);
+
+This registers the function C<mylookup()> under the C<lookup> hook with the
+private context given by the variable C<mycontext>. And it registers the
+function C<mysetup()> under the C<setup> hook without any context. Same for
+C<myread> and C<mylogit>.
+
+=item B<4. Usage>
+
+Finally use the hooks, i.e. instead of using direct function calls like
+        
+ rc = mylookup(a1, a2);
+ rc = mysetup(a1, a2);
+ myread(a1);
+ mylogit(a1);
+
+you now use:
+
+ ap_hook_call("lookup", &rc, a1, a2);
+ ap_hook_call("setup", &rc, a1, a2);
+ ap_hook_call("read", a1);
+ ap_hook_call("logit", a1);
+
+which are internally translated to:
+
+ rc = mylookup(a1, a2, mycontext);
+ rc = mysetup(a1, a2);
+ myread(a1);
+ mylogit(a1);
+
+Notice two things here: First the context (C<mycontext>) for the C<mylookup()>
+function is automatically added by the hook mechanism. And it is a different
+(and not fixed) context for each registered function, of course.  Second,
+return values always have to be pushed into variables and a pointer to them
+has to be given as the second argument to C<ap_hook_call> (except for
+functions which have a void return type, of course).
+
+BTW, the return value of C<ap_hook_call()> is always C<TRUE> or C<FALSE>.
+C<TRUE> when at least one function call was successful (always the case for
+C<AP_HOOK_TOPMOST> and C<AP_HOOK_ALL>). C<FALSE> when all functions
+returned the decline value or no functions are registered at all.
+
+=back
+
+=head1 RESTRICTIONS
+
+To make the hook implementation efficient and to not bloat up the code too
+much a few restrictions have to make:
+
+=over 3
+
+=item 1.
+
+Only function calls with up to 4 arguments are implemented. When more are
+needed you can either extend the hook implementation by using more bits for
+the signature configuration or you can do a workaround when the function is
+your own one: Put the remaining (N-4-1) arguments into a structure and pass
+only a pointer (one argument) as the forth argument.
+
+=item 2.
+
+Only the following ANSI C variable types are supported:
+
+ - For the return value: 
+   void (= none), char, int, float, double, ptr (= void *)
+ - For the arguments:
+   ctx  (= context), char, int, float, double, ptr (= void *)
+
+This means in theory that 6^5 (=7776) signature combinations are possible. But
+because we don't need all of them inside Apache and it would bloat up the code
+too dramatically we implement only a subset of those combinations. The
+implemented signatures can be specified inside C<ap_hook.c> and the
+corresponding code can be automatically generated by running ``C<perl
+ap_hook.c>'' (yeah, no joke ;-).  So when you need a hook with a different
+still not implemented signature you either have to again use a workaround as
+above (i.e. use a structure) or just add the signature to the C<ap_hook.c>
+file.
+
+=head1 EXAMPLE
+
+We want to call `C<ssize_t read(int, void *, size_t)>' through hooks in order
+to allow modules to override this call.  So, somewhere we have a replacement
+function for C<read()> defined (same signature, of course):
+
+ ssize_t my_read(int, void *, size_t);
+
+We now configure a C<read> hook. Here the C<AP_HOOK_SIGx()> macro defines the
+signature of the C<read()>-like callback functions and has to match the
+prototype of C<read()>. But we have to replace typedefs with the physical
+underlaying ANSI C types. And C<AP_HOOK_DECLINE()> sets the return value of
+the read()-like functions which forces the next hook to be called (here -1).
+And we register the original C<read()> function as the default hook.
+
+ ap_hook_configure("read", 
+                   AP_HOOK_SIG4(int,int,ptr,int), 
+                   AP_HOOK_DECLINE(-1));
+ ap_hook_register("read", read);
+
+Now a module wants to override the C<read()> call and registers the
+C<my_read()> function:
+
+ ap_hook_register("read", my_read);
+
+The function logically gets pushed onto a stack, so the execution order is the
+reverse registering order, i.e. I<last registered - first called>. Now we can
+replace the standard C<read()> call
+
+ bytes = read(fd, buf, bufsize);
+ if (bytes == -1)
+    ...error...
+
+with the hook based call:
+
+  rc = ap_hook_call("read", &bytes, fd, buf, bufsize);
+  if (rc == FALSE)
+     ...error...
+
+Now internally the following is done: The call `C<bytes = my_read(fd, buf,
+bufsize)>' is done. When it returns not -1 (the decline value) nothing
+more is done. But when C<my_read()> returns -1 the next function is tried:
+`C<bytes = read(fd, buf, bufsize)>'. When this one also returns -1 you get
+`rc == FALSE'. When it finally returns not -1 you get `rc == TRUE'.
+
+=head1 SEE ALSO
+
+ap_ctx(3)
+
+=head1 HISTORY
+
+The ap_hook(3) interface was originally designed and 
+implemented in October 1998 by Ralf S. Engelschall.
+
+=head1 AUTHOR
+
+ Ralf S. Engelschall
+ rse@engelschall.com
+ www.engelschall.com
+
+=cut
+*/
diff -urN apache_1.3.29/src/include/ap_mm.h apache-1.3.29-2/src/include/ap_mm.h
--- apache_1.3.29/src/include/ap_mm.h	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/include/ap_mm.h	1999-12-30 22:02:59.000000000 +0100
@@ -0,0 +1,130 @@
+/* ====================================================================
+ * Copyright (c) 1999-2000 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ */
+
+/*
+**
+** ap_mm.h -- wrapper code for MM shared memory library
+**
+*/
+
+#ifdef EAPI
+
+#ifndef AP_MM_H 
+#define AP_MM_H 1
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  !FALSE
+#endif
+
+API_EXPORT(int) ap_mm_useable(void);
+
+typedef void AP_MM;
+typedef enum { AP_MM_LOCK_RD, AP_MM_LOCK_RW } ap_mm_lock_mode;
+
+/* Global Malloc-Replacement API */
+API_EXPORT(int)     ap_MM_create(size_t size, char *file);
+API_EXPORT(int)     ap_MM_permission(mode_t mode, uid_t owner, gid_t group);
+API_EXPORT(void)    ap_MM_destroy(void);
+API_EXPORT(int)     ap_MM_lock(ap_mm_lock_mode mode);
+API_EXPORT(int)     ap_MM_unlock(void);
+API_EXPORT(void *)  ap_MM_malloc(size_t size);
+API_EXPORT(void *)  ap_MM_realloc(void *ptr, size_t size);
+API_EXPORT(void)    ap_MM_free(void *ptr);
+API_EXPORT(void *)  ap_MM_calloc(size_t number, size_t size);
+API_EXPORT(char *)  ap_MM_strdup(const char *str);
+API_EXPORT(size_t)  ap_MM_sizeof(void *ptr);
+API_EXPORT(size_t)  ap_MM_maxsize(void);
+API_EXPORT(size_t)  ap_MM_available(void);
+API_EXPORT(char *)  ap_MM_error(void);
+
+/* Standard Malloc-Style API */
+API_EXPORT(AP_MM *) ap_mm_create(size_t size, char *file);
+API_EXPORT(int)     ap_mm_permission(AP_MM *mm, mode_t mode, uid_t owner, gid_t group);
+API_EXPORT(void)    ap_mm_destroy(AP_MM *mm);
+API_EXPORT(int)     ap_mm_lock(AP_MM *mm, ap_mm_lock_mode mode);
+API_EXPORT(int)     ap_mm_unlock(AP_MM *mm);
+API_EXPORT(void *)  ap_mm_malloc(AP_MM *mm, size_t size);
+API_EXPORT(void *)  ap_mm_realloc(AP_MM *mm, void *ptr, size_t size);
+API_EXPORT(void)    ap_mm_free(AP_MM *mm, void *ptr);
+API_EXPORT(void *)  ap_mm_calloc(AP_MM *mm, size_t number, size_t size);
+API_EXPORT(char *)  ap_mm_strdup(AP_MM *mm, const char *str);
+API_EXPORT(size_t)  ap_mm_sizeof(AP_MM *mm, void *ptr);
+API_EXPORT(size_t)  ap_mm_maxsize(void);
+API_EXPORT(size_t)  ap_mm_available(AP_MM *mm);
+API_EXPORT(char *)  ap_mm_error(void);
+API_EXPORT(void)    ap_mm_display_info(AP_MM *mm);
+
+/* Low-Level Shared Memory API */
+API_EXPORT(void *)  ap_mm_core_create(size_t size, char *file);
+API_EXPORT(int)     ap_mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group);
+API_EXPORT(void)    ap_mm_core_delete(void *core);
+API_EXPORT(size_t)  ap_mm_core_size(void *core);
+API_EXPORT(int)     ap_mm_core_lock(void *core, ap_mm_lock_mode mode);
+API_EXPORT(int)     ap_mm_core_unlock(void *core);
+API_EXPORT(size_t)  ap_mm_core_maxsegsize(void);
+API_EXPORT(size_t)  ap_mm_core_align2page(size_t size);
+API_EXPORT(size_t)  ap_mm_core_align2word(size_t size);
+
+/* Internal Library API */
+API_EXPORT(void)    ap_mm_lib_error_set(unsigned int, const char *str);
+API_EXPORT(char *)  ap_mm_lib_error_get(void);
+API_EXPORT(int)     ap_mm_lib_version(void);
+
+#endif /* AP_MM_H */
+
+#endif /* EAPI */
+
diff -urN apache_1.3.29/src/include/ap_mmn.h apache-1.3.29-2/src/include/ap_mmn.h
--- apache_1.3.29/src/include/ap_mmn.h	2003-07-07 02:34:09.000000000 +0200
+++ apache-1.3.29-2/src/include/ap_mmn.h	2003-12-10 01:12:51.000000000 +0100
@@ -245,7 +245,23 @@
  * 19990320.15          - ap_is_recursion_limit_exceeded()
  */
 
+/* 
+ * Under Extended API situations we replace the magic cookie "AP13" with
+ * "EAPI" to let us distinguish between the EAPI module structure (which
+ * contain additional pointers at the end) and standard module structures
+ * (which lack at least NULL's for the pointers at the end).  This is
+ * important because standard ("AP13") modules would dump core when we
+ * dispatch over the additional hooks because NULL's are missing at the end of
+ * the module structure. See also the code in mod_so for details on loading
+ * (we accept both "AP13" and "EAPI").
+ */
+#ifdef EAPI
+#define MODULE_MAGIC_COOKIE_AP13 0x41503133UL /* "AP13" */
+#define MODULE_MAGIC_COOKIE_EAPI 0x45415049UL /* "EAPI" */
+#define MODULE_MAGIC_COOKIE      MODULE_MAGIC_COOKIE_EAPI 
+#else
 #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
+#endif
 
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 19990320
diff -urN apache_1.3.29/src/include/buff.h apache-1.3.29-2/src/include/buff.h
--- apache_1.3.29/src/include/buff.h	2003-02-03 18:13:18.000000000 +0100
+++ apache-1.3.29-2/src/include/buff.h	2003-12-10 01:12:51.000000000 +0100
@@ -125,6 +125,10 @@
     /* transport handle, for RPC binding handle or some such */
     void *t_handle;
 
+#ifdef EAPI
+    ap_ctx *ctx;
+#endif /* EAPI */
+
 #ifdef B_SFIO
     Sfio_t *sf_in;
     Sfio_t *sf_out;
@@ -181,6 +185,10 @@
 API_EXPORT(int) ap_bflsbuf(int c, BUFF *fb);
 API_EXPORT(int) ap_bfilbuf(BUFF *fb);
 
+#ifdef EAPI
+#define ap_bpeekc(fb) ( ((fb)->incnt == 0) ? EOF : *((fb)->inptr) )
+#endif
+
 #ifndef CHARSET_EBCDIC
 
 #define ap_bgetc(fb)   ( ((fb)->incnt == 0) ? ap_bfilbuf(fb) : \
diff -urN apache_1.3.29/src/include/http_conf_globals.h apache-1.3.29-2/src/include/http_conf_globals.h
--- apache_1.3.29/src/include/http_conf_globals.h	2003-02-03 18:13:18.000000000 +0100
+++ apache-1.3.29-2/src/include/http_conf_globals.h	2003-12-10 01:12:51.000000000 +0100
@@ -95,6 +95,9 @@
 #endif
 extern int ap_dump_settings;
 extern API_VAR_EXPORT int ap_extended_status;
+#ifdef EAPI
+extern API_VAR_EXPORT ap_ctx *ap_global_ctx;
+#endif /* EAPI */
 
 extern API_VAR_EXPORT char *ap_pid_fname;
 extern API_VAR_EXPORT char *ap_scoreboard_fname;
diff -urN apache_1.3.29/src/include/http_config.h apache-1.3.29-2/src/include/http_config.h
--- apache_1.3.29/src/include/http_config.h	2003-02-03 18:13:18.000000000 +0100
+++ apache-1.3.29-2/src/include/http_config.h	2003-12-10 01:12:51.000000000 +0100
@@ -276,6 +276,65 @@
     void (*child_exit) (server_rec *, pool *);
 #endif
     int (*post_read_request) (request_rec *);
+
+#ifdef EAPI
+    /*
+     * ANSI C guarantees us that we can at least _extend_ the module structure
+     * with additional hooks without the need to change all existing modules.
+     * Because: ``If there are fewer initializers in the list than members of
+     * the structure, the trailing members are initialized with 0.'' (The C
+     * Programming Language, 2nd Ed., A8.7 Initialization). So we just
+     * have to put our additional hooks here:
+     *
+     * add_module: 
+     *     Called from within ap_add_module() right after the module structure
+     *     was linked into the Apache internal module list.  It is mainly
+     *     intended to be used to define configuration defines (<IfDefine>)
+     *     which have to be available directly after a LoadModule/AddModule.
+     *     Actually this is the earliest possible hook a module can use.
+     *
+     * remove_module: 
+     *     Called from within ap_remove_module() right before the module
+     *     structure is kicked out from the Apache internal module list.
+     *     Actually this is last possible hook a module can use and exists for
+     *     consistency with the add_module hook.
+     *
+     * rewrite_command:
+     *     Called right after a configuration directive line was read and
+     *     before it is processed. It is mainly intended to be used for
+     *     rewriting directives in order to provide backward compatibility to
+     *     old directive variants.
+     *
+     * new_connection:
+     *     Called from within the internal new_connection() function, right
+     *     after the conn_rec structure for the new established connection was
+     *     created and before Apache starts processing the request with
+     *     ap_read_request().  It is mainly intended to be used to setup/run
+     *     connection dependent things like sending start headers for
+     *     on-the-fly compression, etc.
+     *
+     * close_connection:
+     *     Called from within the Apache dispatching loop just before any
+     *     ap_bclose() is performed on the socket connection, but a long time
+     *     before any pool cleanups are done for the connection (which can be
+     *     too late for some applications).  It is mainly intended to be used
+     *     to close/finalize connection dependent things like sending end
+     *     headers for on-the-fly compression, etc.
+     */
+#ifdef ULTRIX_BRAIN_DEATH
+    void  (*add_module) ();
+    void  (*remove_module) ();
+    char *(*rewrite_command) ();
+    void  (*new_connection) ();
+    void  (*close_connection) ();
+#else
+    void  (*add_module) (struct module_struct *);
+    void  (*remove_module) (struct module_struct *);
+    char *(*rewrite_command) (cmd_parms *, void *config, const char *);
+    void  (*new_connection) (conn_rec *);
+    void  (*close_connection) (conn_rec *);
+#endif
+#endif /* EAPI */
 } module;
 
 /* Initializer for the first few module slots, which are only
diff -urN apache_1.3.29/src/include/httpd.h apache-1.3.29-2/src/include/httpd.h
--- apache_1.3.29/src/include/httpd.h	2003-10-24 18:11:40.000000000 +0200
+++ apache-1.3.29-2/src/include/httpd.h	2003-12-10 01:12:51.000000000 +0100
@@ -70,7 +70,19 @@
 /* Headers in which EVERYONE has an interest... */
 
 #include "ap_config.h"
+#ifdef EAPI
+#include "ap_mm.h"
+#endif
 #include "ap_alloc.h"
+/*
+ * Include the Extended API headers.
+ * Don't move the position. It has to be after ap_alloc.h because it uses the
+ * pool stuff but before buff.h because the buffer stuff uses the EAPI, too. 
+ */
+#ifdef EAPI
+#include "ap_hook.h"
+#include "ap_ctx.h"
+#endif /* EAPI */
 #include "buff.h"
 #include "ap.h"
 
@@ -145,8 +157,13 @@
 #define ap_http_method(r) ap_os_http_method((void*)r)
 #define ap_default_port(r) ap_os_default_port((void*)r)
 #else
+#ifdef EAPI
+#define ap_http_method(r)   (((r)->ctx != NULL && ap_ctx_get((r)->ctx, "ap::http::method") != NULL) ? ((char *)ap_ctx_get((r)->ctx, "ap::http::method")) : "http")
+#define ap_default_port(r)  (((r)->ctx != NULL && ap_ctx_get((r)->ctx, "ap::default::port") != NULL) ? atoi((char *)ap_ctx_get((r)->ctx, "ap::default::port")) : DEFAULT_HTTP_PORT)
+#else /* EAPI */
 #define ap_http_method(r)	"http"
 #define ap_default_port(r)	DEFAULT_HTTP_PORT
+#endif /* EAPI */
 #endif
 
 /* --------- Default user name and group name running standalone ---------- */
@@ -355,6 +372,19 @@
 #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
 #endif
 
+/*
+ * Unix only:
+ * Path to Shared Memory Files 
+ */
+#ifdef EAPI
+#ifndef EAPI_MM_CORE_PATH
+#define EAPI_MM_CORE_PATH "logs/mm"
+#endif
+#ifndef EAPI_MM_CORE_MAXSIZE
+#define EAPI_MM_CORE_MAXSIZE 1024*1024*1 /* max. 1MB */
+#endif
+#endif
+
 /* Number of requests to try to handle in a single process.  If <= 0,
  * the children don't die off.  That's the default here, since I'm still
  * interested in finding and stanching leaks.
@@ -447,6 +477,9 @@
 API_EXPORT(const char *) ap_get_server_version(void);
 API_EXPORT(void) ap_add_version_component(const char *component);
 API_EXPORT(const char *) ap_get_server_built(void);
+#ifdef EAPI
+API_EXPORT(void) ap_add_config_define(const char *define);
+#endif /* EAPI */
 
 /* Numeric release version identifier: MMNNFFRBB: major minor fix final beta
  * Always increases along the same track as the source branch.
@@ -850,6 +883,10 @@
  * record to improve 64bit alignment the next time we need to break
  * binary compatibility for some other reason.
  */
+
+#ifdef EAPI
+    ap_ctx *ctx;
+#endif /* EAPI */
 };
 
 
@@ -898,6 +935,9 @@
     char *local_host;		/* used for ap_get_server_name when
 				 * UseCanonicalName is set to DNS
 				 * (ignores setting of HostnameLookups) */
+#ifdef EAPI
+    ap_ctx *ctx;
+#endif /* EAPI */
 };
 
 /* Per-vhost config... */
@@ -970,6 +1010,10 @@
     int limit_req_line;      /* limit on size of the HTTP request line    */
     int limit_req_fieldsize; /* limit on size of any request header field */
     int limit_req_fields;    /* limit on number of request header fields  */
+
+#ifdef EAPI
+    ap_ctx *ctx;
+#endif /* EAPI */
 };
 
 /* These are more like real hosts than virtual hosts */
diff -urN apache_1.3.29/src/main/alloc.c apache-1.3.29-2/src/main/alloc.c
--- apache_1.3.29/src/main/alloc.c	2003-09-05 14:27:30.000000000 +0200
+++ apache-1.3.29-2/src/main/alloc.c	2003-12-10 01:12:51.000000000 +0100
@@ -64,6 +64,10 @@
  */
 
 #include "httpd.h"
+#ifdef EAPI
+#include "http_config.h"
+#include "http_conf_globals.h"
+#endif
 #include "multithread.h"
 #include "http_log.h"
 
@@ -138,6 +142,10 @@
 #define BLOCK_MINALLOC	0
 #endif
 
+#if defined(EAPI) && defined(EAPI_MM)
+static AP_MM *mm = NULL;
+#endif
+
 /*****************************************************************
  *
  * Managing free storage blocks...
@@ -166,6 +174,9 @@
 	char *endp;
 	union block_hdr *next;
 	char *first_avail;
+#if defined(EAPI) && defined(EAPI_MM)
+	int is_shm;
+#endif
 #ifdef POOL_DEBUG
 	union block_hdr *global_next;
 	struct pool *owning_pool;
@@ -216,7 +227,11 @@
 /* Get a completely new block from the system pool. Note that we rely on
    malloc() to provide aligned memory. */
 
+#if defined(EAPI) && defined(EAPI_MM)
+static union block_hdr *malloc_block(int size, int is_shm)
+#else
 static union block_hdr *malloc_block(int size)
+#endif
 {
     union block_hdr *blok;
     int request_size;
@@ -232,6 +247,11 @@
     num_malloc_bytes += size + sizeof(union block_hdr);
 #endif
     request_size = size + sizeof(union block_hdr);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (is_shm)
+        blok = (union block_hdr *)ap_mm_malloc(mm, request_size);
+    else
+#endif
     blok = (union block_hdr *) malloc(request_size);
     if (blok == NULL) {
 	fprintf(stderr, "Ouch!  malloc(%d) failed in malloc_block()\n",
@@ -239,6 +259,9 @@
 	exit(1);
     }
     debug_fill(blok, size + sizeof(union block_hdr));
+#if defined(EAPI) && defined(EAPI_MM)
+    blok->h.is_shm = is_shm;
+#endif
     blok->h.next = NULL;
     blok->h.first_avail = (char *) (blok + 1);
     blok->h.endp = size + blok->h.first_avail;
@@ -299,6 +322,10 @@
     if (blok == NULL)
 	return;			/* Sanity check --- freeing empty pool? */
 
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm)
+        (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
     (void) ap_acquire_mutex(alloc_mutex);
     old_free_list = block_freelist;
     block_freelist = blok;
@@ -345,6 +372,10 @@
 #endif
 
     (void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm)
+        (void)ap_mm_unlock(mm);
+#endif
 #endif
 }
 
@@ -353,7 +384,11 @@
  * if necessary.  Must be called with alarms blocked.
  */
 
+#if defined(EAPI) && defined(EAPI_MM)
+static union block_hdr *new_block(int min_size, int is_shm)
+#else
 static union block_hdr *new_block(int min_size)
+#endif
 {
     union block_hdr **lastptr = &block_freelist;
     union block_hdr *blok = block_freelist;
@@ -363,7 +398,12 @@
      */
 
     while (blok != NULL) {
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm == is_shm &&
+        min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
+#else
 	if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
+#endif
 	    *lastptr = blok->h.next;
 	    blok->h.next = NULL;
 	    debug_verify_filled(blok->h.first_avail, blok->h.endp,
@@ -379,7 +419,11 @@
     /* Nope. */
 
     min_size += BLOCK_MINFREE;
+#if defined(EAPI) && defined(EAPI_MM)
+    blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC, is_shm);
+#else
     blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
+#endif
     return blok;
 }
 
@@ -429,6 +473,9 @@
 #ifdef POOL_DEBUG
     struct pool *joined;
 #endif
+#if defined(EAPI) && defined(EAPI_MM)
+    int is_shm;
+#endif
 };
 
 static pool *permanent_pool;
@@ -443,16 +490,28 @@
 #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))
 #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)
 
+#if defined(EAPI) && defined(EAPI_MM)
+static struct pool *make_sub_pool_internal(struct pool *p, int is_shm)
+#else
 API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
+#endif
 {
     union block_hdr *blok;
     pool *new_pool;
 
     ap_block_alarms();
 
+#if defined(EAPI) && defined(EAPI_MM)
+    if (is_shm)
+        (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
     (void) ap_acquire_mutex(alloc_mutex);
 
+#if defined(EAPI) && defined(EAPI_MM)
+    blok = new_block(POOL_HDR_BYTES, is_shm);
+#else
     blok = new_block(POOL_HDR_BYTES);
+#endif
     new_pool = (pool *) blok->h.first_avail;
     blok->h.first_avail += POOL_HDR_BYTES;
 #ifdef POOL_DEBUG
@@ -471,12 +530,38 @@
 	p->sub_pools = new_pool;
     }
 
+#if defined(EAPI) && defined(EAPI_MM)
+    new_pool->is_shm = is_shm;
+#endif
+
     (void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (is_shm)
+	(void)ap_mm_unlock(mm);
+#endif
     ap_unblock_alarms();
 
     return new_pool;
 }
 
+#if defined(EAPI)
+#if defined(EAPI_MM)
+API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
+{
+    return make_sub_pool_internal(p, 0);
+}
+API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
+{
+    return make_sub_pool_internal(p, 1);
+}
+#else
+API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
+{
+    return NULL;
+}
+#endif
+#endif
+
 #ifdef POOL_DEBUG
 static void stack_var_init(char *s)
 {
@@ -491,6 +576,13 @@
 }
 #endif
 
+#if defined(EAPI)
+int ap_shared_pool_possible(void)
+{
+    return ap_mm_useable();
+}
+#endif
+
 #ifdef ALLOC_STATS
 static void dump_stats(void)
 {
@@ -523,6 +615,58 @@
     return permanent_pool;
 }
 
+#if defined(EAPI)
+void ap_init_alloc_shared(int early)
+{
+#if defined(EAPI_MM)
+    int mm_size;
+    char *mm_path;
+    char *err1, *err2;
+
+    if (early) {
+        /* process very early on startup */
+        mm_size = ap_mm_maxsize();
+        if (mm_size > EAPI_MM_CORE_MAXSIZE)
+            mm_size = EAPI_MM_CORE_MAXSIZE;
+        mm_path = ap_server_root_relative(permanent_pool, 
+                  ap_psprintf(permanent_pool, "%s.%ld", 
+                              EAPI_MM_CORE_PATH, (long)getpid()));
+        if ((mm = ap_mm_create(mm_size, mm_path)) == NULL) {
+            fprintf(stderr, "Ouch! ap_mm_create(%d, \"%s\") failed\n", mm_size, mm_path);
+            err1 = ap_mm_error();
+            if (err1 == NULL)
+                err1 = "-unknown-";
+            err2 = strerror(errno);
+            if (err2 == NULL)
+                err2 = "-unknown-";
+            fprintf(stderr, "Error: MM: %s: OS: %s\n", err1, err2);
+            exit(1);
+        }
+    }
+    else {
+        /* process a lot later on startup */
+#ifdef WIN32
+        ap_mm_permission(mm, (_S_IREAD|_S_IWRITE), ap_user_id, -1);
+#else
+        ap_mm_permission(mm, (S_IRUSR|S_IWUSR), ap_user_id, -1);
+#endif
+    }
+#endif /* EAPI_MM */
+    return; 
+}
+
+void ap_kill_alloc_shared(void)
+{
+#if defined(EAPI_MM)
+    if (mm != NULL) {
+        ap_mm_destroy(mm);
+        mm = NULL;
+    }
+#endif /* EAPI_MM */
+    return;
+}
+#endif /* EAPI */
+
 void ap_cleanup_alloc(void)
 {
     ap_destroy_mutex(alloc_mutex);
@@ -533,10 +677,18 @@
 {
     ap_block_alarms();
 
+#if defined(EAPI) && defined(EAPI_MM)
+    if (a->is_shm)
+        (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
     (void) ap_acquire_mutex(alloc_mutex);
     while (a->sub_pools)
 	ap_destroy_pool(a->sub_pools);
     (void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (a->is_shm)
+	    (void)ap_mm_unlock(mm);
+#endif
     /* Don't hold the mutex during cleanups. */
     run_cleanups(a->cleanups);
     a->cleanups = NULL;
@@ -570,6 +722,10 @@
     ap_block_alarms();
     ap_clear_pool(a);
 
+#if defined(EAPI) && defined(EAPI_MM)
+    if (a->is_shm)
+	(void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
     (void) ap_acquire_mutex(alloc_mutex);
     if (a->parent) {
 	if (a->parent->sub_pools == a)
@@ -580,6 +736,10 @@
 	    a->sub_next->sub_prev = a->sub_prev;
     }
     (void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (a->is_shm)
+	(void)ap_mm_unlock(mm);
+#endif
 
     free_blocks(a->first);
     ap_unblock_alarms();
@@ -594,6 +754,30 @@
     return bytes_in_block_list(block_freelist);
 }
 
+#if defined(EAPI)
+API_EXPORT(int) ap_acquire_pool(pool *p, ap_pool_lock_mode mode)
+{
+#if defined(EAPI_MM)
+    if (!p->is_shm)
+        return 1;
+    return ap_mm_lock(mm, mode == AP_POOL_RD ? AP_MM_LOCK_RD : AP_MM_LOCK_RW);
+#else
+	return 1;
+#endif
+}
+
+API_EXPORT(int) ap_release_pool(pool *p)
+{
+#if defined(EAPI_MM)
+    if (!p->is_shm)
+        return 1;
+    return ap_mm_unlock(mm);
+#else
+	return 1;
+#endif
+}
+#endif /* EAPI */
+
 /*****************************************************************
  * POOL_DEBUG support
  */
@@ -759,16 +943,31 @@
 
     ap_block_alarms();
 
+#if defined(EAPI) && defined(EAPI_MM)
+    if (a->is_shm)
+	(void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
     (void) ap_acquire_mutex(alloc_mutex);
 
+#if defined(EAPI) && defined(EAPI_MM)
+    blok = new_block(size, a->is_shm);
+#else
     blok = new_block(size);
+#endif
     a->last->h.next = blok;
     a->last = blok;
 #ifdef POOL_DEBUG
     blok->h.owning_pool = a;
 #endif
+#if defined(EAPI) && defined(EAPI_MM)
+    blok->h.is_shm = a->is_shm;
+#endif
 
     (void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (a->is_shm)
+	(void)ap_mm_unlock(mm);
+#endif
 
     ap_unblock_alarms();
 
@@ -885,6 +1084,11 @@
     size = cur_len << 1;
     if (size < AP_PSPRINTF_MIN_SIZE)
         size = AP_PSPRINTF_MIN_SIZE;
+#if defined(EAPI) && defined(EAPI_MM)
+    if (ps->block->h.is_shm)
+        ptr = ap_mm_realloc(ps->base, size);
+    else
+#endif
     ptr = realloc(ps->base, size);
     if (ptr == NULL) {
 	fputs("Ouch!  Out of memory!\n", stderr);
@@ -908,9 +1112,21 @@
         size = AP_PSPRINTF_MIN_SIZE;
 
     /* must try another blok */
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm)
+	(void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
     (void) ap_acquire_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    nblok = new_block(size, blok->h.is_shm);
+#else
     nblok = new_block(size);
+#endif
     (void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm)
+	(void)ap_mm_unlock(mm);
+#endif
     memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len);
     ps->vbuff.curpos = nblok->h.first_avail + cur_len;
     /* save a byte for the NUL terminator */
@@ -919,10 +1135,18 @@
     /* did we allocate the current blok? if so free it up */
     if (ps->got_a_new_block) {
 	debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm)
+	(void)ap_mm_lock(mm, AP_MM_LOCK_RW);
+#endif
 	(void) ap_acquire_mutex(alloc_mutex);
 	blok->h.next = block_freelist;
 	block_freelist = blok;
 	(void) ap_release_mutex(alloc_mutex);
+#if defined(EAPI) && defined(EAPI_MM)
+    if (blok->h.is_shm)
+	(void)ap_mm_unlock(mm);
+#endif
     }
     ps->blok = nblok;
     ps->got_a_new_block = 1;
@@ -941,6 +1165,11 @@
     void *ptr;
 
     ap_block_alarms();
+#if defined(EAPI) && defined(EAPI_MM)
+    if (p->is_shm)
+        ps.base = ap_mm_malloc(mm, 512);
+    else
+#endif
     ps.base = malloc(512);
     if (ps.base == NULL) {
 	fputs("Ouch!  Out of memory!\n", stderr);
@@ -953,6 +1182,11 @@
     *ps.vbuff.curpos++ = '\0';
     ptr = ps.base;
     /* shrink */
+#if defined(EAPI) && defined(EAPI_MM)
+    if (p->is_shm)
+        ptr = ap_mm_realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
+    else
+#endif
     ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
     if (ptr == NULL) {
 	fputs("Ouch!  Out of memory!\n", stderr);
diff -urN apache_1.3.29/src/main/buff.c apache-1.3.29-2/src/main/buff.c
--- apache_1.3.29/src/main/buff.c	2003-10-19 20:00:35.000000000 +0200
+++ apache-1.3.29-2/src/main/buff.c	2003-12-10 01:12:51.000000000 +0100
@@ -293,6 +293,9 @@
     }
     else
 #endif
+#ifdef EAPI
+	if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
+#endif /* EAPI */
 	rv = read(fb->fd_in, buf, nbyte);
     
     return rv;
@@ -304,6 +307,9 @@
 
 #if defined (WIN32) || defined(NETWARE) || defined(CYGWIN_WINSOCK) 
     if (fb->flags & B_SOCKET) {
+#ifdef EAPI
+	if (!ap_hook_call("ap::buff::recvwithtimeout", &rv, fb, buf, nbyte))
+#endif /* EAPI */
 	rv = ap_recvwithtimeout(fb->fd_in, buf, nbyte, 0);
 	if (rv == SOCKET_ERROR)
 	    errno = WSAGetLastError();
@@ -351,6 +357,9 @@
     }
     else
 #endif
+#ifdef EAPI
+	if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
+#endif /* EAPI */
 #if defined (B_SFIO)
 	rv = sfwrite(fb->sf_out, buf, nbyte);
 #else
@@ -381,6 +390,9 @@
    
 #if defined(WIN32) || defined(NETWARE)
     if (fb->flags & B_SOCKET) {
+#ifdef EAPI
+	if (!ap_hook_call("ap::buff::sendwithtimeout", &rv, fb, buf, nbyte))
+#endif /* EAPI */
 	rv = ap_sendwithtimeout(fb->fd, buf, nbyte, 0);
 	if (rv == SOCKET_ERROR)
 	    errno = WSAGetLastError();
@@ -464,6 +476,10 @@
     fb->callback_data = NULL;
     fb->filter_callback = NULL;
 
+#ifdef EAPI
+    fb->ctx = ap_ctx_new(p);
+#endif /* EAPI */
+
     return fb;
 }
 
@@ -1116,6 +1132,9 @@
     i = 0;
     while (i < nvec) {
 	do
+#ifdef EAPI
+	    if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
+#endif /* EAPI */
 	    rv = writev(fb->fd, &vec[i], nvec - i);
 	while (rv == -1 && (errno == EINTR || errno == EAGAIN)
 	       && !(fb->flags & B_EOUT));
diff -urN apache_1.3.29/src/main/http_config.c apache-1.3.29-2/src/main/http_config.c
--- apache_1.3.29/src/main/http_config.c	2003-02-03 18:13:21.000000000 +0100
+++ apache-1.3.29-2/src/main/http_config.c	2003-12-10 01:12:51.000000000 +0100
@@ -600,6 +600,20 @@
 	m->name = tmp;
     }
 #endif /*_OSD_POSIX*/
+
+#ifdef EAPI
+    /*
+     * Invoke the `add_module' hook inside the now existing set
+     * of modules to let them all now that this module was added.
+     */
+    {
+        module *m2;
+        for (m2 = top_module; m2 != NULL; m2 = m2->next)
+            if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
+                if (m2->add_module != NULL)
+                    (*m2->add_module)(m);
+    }
+#endif /* EAPI */
 }
 
 /* 
@@ -614,6 +628,21 @@
 {
     module *modp;
 
+#ifdef EAPI
+    /*
+     * Invoke the `remove_module' hook inside the now existing
+     * set of modules to let them all now that this module is
+     * beeing removed.
+     */
+    {
+        module *m2;
+        for (m2 = top_module; m2 != NULL; m2 = m2->next)
+            if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
+                if (m2->remove_module != NULL)
+                    (*m2->remove_module)(m);
+    }
+#endif /* EAPI */
+
     modp = top_module;
     if (modp == m) {
 	/* We are the top module, special case */
@@ -1007,6 +1036,27 @@
     const command_rec *cmd;
     module *mod = top_module;
 
+#ifdef EAPI
+    /*
+     * Invoke the `rewrite_command' of modules to allow
+     * they to rewrite the directive line before we
+     * process it.
+     */
+    {
+        module *m;
+        char *cp;
+        for (m = top_module; m != NULL; m = m->next) {
+            if (m->magic == MODULE_MAGIC_COOKIE_EAPI) {
+                if (m->rewrite_command != NULL) {
+                    cp = (m->rewrite_command)(parms, config, l);
+                    if (cp != NULL)
+                        l = cp;
+                }
+            }
+        }
+    }
+#endif /* EAPI */
+
     if ((l[0] == '#') || (!l[0]))
 	return NULL;
 
@@ -1467,6 +1517,10 @@
     s->limit_req_fieldsize = main_server->limit_req_fieldsize;
     s->limit_req_fields = main_server->limit_req_fields;
 
+#ifdef EAPI
+    s->ctx = ap_ctx_new(p);
+#endif /* EAPI */
+
     *ps = s;
 
     return ap_parse_vhost_addrs(p, hostname, s);
@@ -1578,6 +1632,10 @@
     s->module_config = create_server_config(p, s);
     s->lookup_defaults = create_default_per_dir_config(p);
 
+#ifdef EAPI
+    s->ctx = ap_ctx_new(p);
+#endif /* EAPI */
+
     return s;
 }
 
diff -urN apache_1.3.29/src/main/http_main.c apache-1.3.29-2/src/main/http_main.c
--- apache_1.3.29/src/main/http_main.c	2003-10-19 20:00:35.000000000 +0200
+++ apache-1.3.29-2/src/main/http_main.c	2003-12-10 01:12:51.000000000 +0100
@@ -279,6 +279,9 @@
 
 int ap_dump_settings = 0;
 API_VAR_EXPORT int ap_extended_status = 0;
+#ifdef EAPI
+API_VAR_EXPORT ap_ctx *ap_global_ctx;
+#endif /* EAPI */
 
 /*
  * The max child slot ever assigned, preserved across restarts.  Necessary
@@ -471,6 +474,30 @@
     }
 }
 
+#ifdef EAPI
+API_EXPORT(void) ap_add_config_define(const char *define)
+{
+    char **var;
+    var = (char **)ap_push_array(ap_server_config_defines);
+    *var = ap_pstrdup(pcommands, define);
+    return;
+}
+
+/*
+ * Invoke the `close_connection' hook of modules to let them do
+ * some connection dependent actions before we close it.
+ */
+static void ap_call_close_connection_hook(conn_rec *c)
+{
+    module *m;
+    for (m = top_module; m != NULL; m = m->next)
+        if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
+            if (m->close_connection != NULL)
+                (*m->close_connection)(c);
+    return;
+}
+#endif /* EAPI */
+
 #ifndef NETWARE
 static APACHE_TLS int volatile exit_after_unblock = 0;
 #endif
@@ -1577,6 +1604,10 @@
 	    ap_log_transaction(log_req);
 	}
 
+#ifdef EAPI
+	ap_call_close_connection_hook(save_req->connection);
+#endif /* EAPI */
+
 	ap_bsetflag(save_req->connection->client, B_EOUT, 1);
 	ap_bclose(save_req->connection->client);
 	
@@ -1585,6 +1616,9 @@
         ap_longjmp(jmpbuffer, 1);
     }
     else {			/* abort the connection */
+#ifdef EAPI
+	ap_call_close_connection_hook(current_conn);
+#endif /* EAPI */
 	ap_bsetflag(current_conn->client, B_EOUT, 1);
 	ap_bclose(current_conn->client);
 	current_conn->aborted = 1;
@@ -1887,10 +1921,16 @@
     /* Send any leftover data to the client, but never try to again */
 
     if (ap_bflush(r->connection->client) == -1) {
+#ifdef EAPI
+	ap_call_close_connection_hook(r->connection);
+#endif /* EAPI */
 	ap_kill_timeout(r);
 	ap_bclose(r->connection->client);
 	return;
     }
+#ifdef EAPI
+    ap_call_close_connection_hook(r->connection);
+#endif /* EAPI */
     ap_bsetflag(r->connection->client, B_EOUT, 1);
 
     /* Close our half of the connection --- send the client a FIN */
@@ -2589,6 +2629,9 @@
     /* Clear the pool - including any registered cleanups */
     ap_destroy_pool(pglobal);
 #endif
+#ifdef EAPI
+    ap_kill_alloc_shared();
+#endif
     exit(code);
 }
 
@@ -3608,6 +3651,24 @@
     conn->remote_addr = *remaddr;
     conn->remote_ip = ap_pstrdup(conn->pool,
 			      inet_ntoa(conn->remote_addr.sin_addr));
+#ifdef EAPI
+    conn->ctx = ap_ctx_new(conn->pool);
+#endif /* EAPI */
+
+#ifdef EAPI
+    /*
+     * Invoke the `new_connection' hook of modules to let them do
+     * some connection dependent actions before we go on with
+     * processing the request on this connection.
+     */
+    {
+        module *m;
+        for (m = top_module; m != NULL; m = m->next)
+            if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
+                if (m->new_connection != NULL)
+                    (*m->new_connection)(conn);
+    }
+#endif /* EAPI */
 
     return conn;
 }
@@ -4023,6 +4084,15 @@
     printf("Server's Module Magic Number: %u:%u\n",
 	   MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
     printf("Server compiled with....\n");
+#ifdef EAPI
+    printf(" -D EAPI\n");
+#endif
+#ifdef EAPI_MM
+    printf(" -D EAPI_MM\n");
+#ifdef EAPI_MM_CORE_PATH
+    printf(" -D EAPI_MM_CORE_PATH=\"" EAPI_MM_CORE_PATH "\"\n");
+#endif
+#endif
 #ifdef TPF
     show_os_specific_compile_settings();
 #endif
@@ -4194,6 +4264,22 @@
     ap_server_pre_read_config  = ap_make_array(pcommands, 1, sizeof(char *));
     ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
     ap_server_config_defines   = ap_make_array(pcommands, 1, sizeof(char *));
+
+#ifdef EAPI
+    ap_hook_init();
+    ap_hook_configure("ap::buff::read", 
+                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+    ap_hook_configure("ap::buff::write",  
+                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+    ap_hook_configure("ap::buff::writev",  
+                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+    ap_hook_configure("ap::buff::sendwithtimeout", 
+                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+    ap_hook_configure("ap::buff::recvwithtimeout", 
+                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+
+    ap_global_ctx = ap_ctx_new(NULL);
+#endif /* EAPI */
 }
 
 #ifndef MULTITHREAD
@@ -4655,6 +4741,9 @@
 
 	    ap_sync_scoreboard_image();
 	    if (ap_scoreboard_image->global.running_generation != ap_my_generation) {
+#ifdef EAPI
+		ap_call_close_connection_hook(current_conn);
+#endif /* EAPI */
 		ap_bclose(conn_io);
 		clean_child_exit(0);
 	    }
@@ -4683,6 +4772,9 @@
 	 */
 
 #ifdef NO_LINGCLOSE
+#ifdef EAPI
+	ap_call_close_connection_hook(current_conn);
+#endif /* EAPI */
 	ap_bclose(conn_io);	/* just close it */
 #else
 	if (r && r->connection
@@ -4693,6 +4785,9 @@
 	    lingering_close(r);
 	}
 	else {
+#ifdef EAPI
+	    ap_call_close_connection_hook(current_conn);
+#endif /* EAPI */
 	    ap_bsetflag(conn_io, B_EOUT, 1);
 	    ap_bclose(conn_io);
 	}
@@ -5463,16 +5558,31 @@
 	    usage(argv[0]);
 	}
     }
+#ifdef EAPI
+    ap_init_alloc_shared(TRUE);
+#endif
 
     ap_suexec_enabled = init_suexec();
     server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
 
+#ifdef EAPI
+    ap_init_alloc_shared(FALSE);
+#endif
+
     if (ap_configtestonly) {
         fprintf(stderr, "Syntax OK\n");
+#ifdef EAPI
+        clean_parent_exit(0);
+#else
         exit(0);
+#endif
     }
     if (ap_dump_settings) {
+#ifdef EAPI
+        clean_parent_exit(0);
+#else
         exit(0);
+#endif
     }
 
     child_timeouts = !ap_standalone || one_process;
@@ -5620,6 +5730,10 @@
 	    ap_destroy_pool(r->pool);
 	}
 
+#ifdef EAPI
+	ap_call_close_connection_hook(conn);
+#endif /* EAPI */
+
 	ap_bclose(cio);
     }
     exit(0);
@@ -5996,6 +6110,9 @@
 	ap_kill_cleanups_for_socket(ptrans, csd);
 
 #ifdef NO_LINGCLOSE
+#ifdef EAPI
+	ap_call_close_connection_hook(current_conn);
+#endif /* EAPI */
 	ap_bclose(conn_io);	/* just close it */
 #else
 	if (r && r->connection
@@ -6006,6 +6123,9 @@
 	    lingering_close(r);
 	}
 	else {
+#ifdef EAPI
+	    ap_call_close_connection_hook(current_conn);
+#endif /* EAPI */
 	    ap_bsetflag(conn_io, B_EOUT, 1);
 	    ap_bclose(conn_io);
 	}
@@ -7574,6 +7694,10 @@
     if (!conf_specified)
         ap_cpystrn(ap_server_confname, SERVER_CONFIG_FILE, sizeof(ap_server_confname));
 
+#ifdef EAPI
+    ap_init_alloc_shared(TRUE);
+#endif
+
     if (!ap_os_is_path_absolute(ap_server_confname))
         ap_cpystrn(ap_server_confname,
                    ap_server_root_relative(pcommands, ap_server_confname),
@@ -7614,6 +7738,9 @@
 #else /* ndef WIN32 */
     server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
 #endif
+#ifdef EAPI
+    ap_init_alloc_shared(FALSE);
+#endif
 
     if (ap_configtestonly) {
         fprintf(stderr, "%s: Syntax OK\n", ap_server_root_relative(pcommands, ap_server_confname));
diff -urN apache_1.3.29/src/main/http_protocol.c apache-1.3.29-2/src/main/http_protocol.c
--- apache_1.3.29/src/main/http_protocol.c	2003-02-03 18:13:22.000000000 +0100
+++ apache-1.3.29-2/src/main/http_protocol.c	2003-12-10 01:12:51.000000000 +0100
@@ -1202,6 +1202,10 @@
     r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
     r->the_request     = NULL;
 
+#ifdef EAPI
+    r->ctx = ap_ctx_new(r->pool);
+#endif /* EAPI */
+
 #ifdef CHARSET_EBCDIC
     ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, r->ebcdic.conv_in  = 1);
     ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, r->ebcdic.conv_out = 1);
@@ -1358,6 +1362,11 @@
     rnew->read_body       = REQUEST_NO_BODY;
 
     rnew->main = (request_rec *) r;
+
+#ifdef EAPI
+    rnew->ctx = r->ctx;
+#endif /* EAPI */
+
 }
 
 API_EXPORT(void) ap_finalize_sub_req_protocol(request_rec *sub)
diff -urN apache_1.3.29/src/main/http_request.c apache-1.3.29-2/src/main/http_request.c
--- apache_1.3.29/src/main/http_request.c	2003-10-18 16:15:58.000000000 +0200
+++ apache-1.3.29-2/src/main/http_request.c	2003-12-10 01:12:51.000000000 +0100
@@ -1406,6 +1406,10 @@
 
     new->method          = r->method;
     new->method_number   = r->method_number;
+#ifdef EAPI
+    /* initialize context _BEFORE_ ap_parse_uri() call */
+    new->ctx             = r->ctx;
+#endif /* EAPI */
     ap_parse_uri(new, new_uri);
     new->request_config = ap_create_request_config(r->pool);
     new->per_dir_config = r->server->lookup_defaults;
diff -urN apache_1.3.29/src/modules/proxy/mod_proxy.c apache-1.3.29-2/src/modules/proxy/mod_proxy.c
--- apache_1.3.29/src/modules/proxy/mod_proxy.c	2003-02-03 18:13:26.000000000 +0100
+++ apache-1.3.29-2/src/modules/proxy/mod_proxy.c	2003-12-10 01:12:51.000000000 +0100
@@ -218,6 +218,9 @@
 static int proxy_fixup(request_rec *r)
 {
     char *url, *p;
+#ifdef EAPI
+    int rc;
+#endif /* EAPI */
 
     if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0)
         return DECLINED;
@@ -225,6 +228,14 @@
     url = &r->filename[6];
 
 /* canonicalise each specific scheme */
+#ifdef EAPI
+    if (ap_hook_use("ap::mod_proxy::canon",
+                    AP_HOOK_SIG3(int,ptr,ptr),
+                    AP_HOOK_DECLINE(DECLINED),
+                    &rc, r, url) && rc != DECLINED)
+        return rc;  
+    else
+#endif /* EAPI */
     if (strncasecmp(url, "http:", 5) == 0)
         return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
     else if (strncasecmp(url, "ftp:", 4) == 0)
@@ -240,9 +251,44 @@
 static void proxy_init(server_rec *r, pool *p)
 {
     ap_proxy_garbage_init(r, p);
+#ifdef EAPI
+    ap_hook_use("ap::mod_proxy::init", 
+                AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p);
+#endif
 }
 
-
+#ifdef EAPI
+static void proxy_addmod(module *m)
+{
+    /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */
+    ap_hook_configure("ap::mod_proxy::http::canon", 
+                      AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
+    ap_hook_register("ap::mod_proxy::http::canon", 
+                     ap_proxy_http_canon, AP_HOOK_NOCTX);
+
+    /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */
+    ap_hook_configure("ap::mod_proxy::http::handler", 
+                      AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
+    ap_hook_register("ap::mod_proxy::http::handler", 
+                     ap_proxy_http_handler, AP_HOOK_NOCTX);
+
+    /* export: ap_proxyerror() as `ap::mod_proxy::error' */
+    ap_hook_configure("ap::mod_proxy::error", 
+                      AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST);
+    ap_hook_register("ap::mod_proxy::error", 
+                     ap_proxyerror, AP_HOOK_NOCTX);
+    return;
+}
+
+static void proxy_remmod(module *m)
+{
+	/* remove the hook references */
+    ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon);
+    ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler);
+    ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror);
+    return;
+}
+#endif /* EAPI */
 
 /* Send a redirection if the request contains a hostname which is not */
 /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
@@ -374,6 +420,14 @@
                  * CONNECT is a special method that bypasses the normal proxy
                  * code.
                  */
+#ifdef EAPI
+		if (!ap_hook_use("ap::mod_proxy::handler",
+				 AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
+				 AP_HOOK_DECLINE(DECLINED),
+				 &rc, r, cr, url, 
+				 ents[i].hostname, ents[i].port, 
+				 ents[i].protocol) || rc == DECLINED) {
+#endif /* EAPI */
                 if (r->method_number == M_CONNECT)
                     rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
                                                   ents[i].port);
@@ -383,6 +437,9 @@
                                                ents[i].port);
                 else
                     rc = DECLINED;
+#ifdef EAPI
+		}
+#endif /* EAPI */
 
                 /* an error or success */
                 if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
@@ -397,6 +454,14 @@
      */
 
     /* handle the scheme */
+#ifdef EAPI
+    if (ap_hook_use("ap::mod_proxy::handler",
+		    AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
+		    AP_HOOK_DECLINE(DECLINED),
+		    &rc, r, cr, url, 
+                    NULL, 0, scheme) && rc != DECLINED)
+        return rc;
+#endif /* EAPI */
     if (r->method_number == M_CONNECT) {
         return ap_proxy_connect_handler(r, cr, url, NULL, 0);
     }
@@ -994,4 +1059,10 @@
     NULL,                       /* child_init */
     NULL,                       /* child_exit */
     proxy_detect                /* post read-request */
+#ifdef EAPI
+   ,proxy_addmod,		/* EAPI: add_module */
+    proxy_remmod,		/* EAPI: remove_module */
+    NULL,			/* EAPI: rewrite_command */
+    NULL			/* EAPI: new_connection  */
+#endif
 };
diff -urN apache_1.3.29/src/modules/proxy/proxy_http.c apache-1.3.29-2/src/modules/proxy/proxy_http.c
--- apache_1.3.29/src/modules/proxy/proxy_http.c	2003-02-03 18:13:26.000000000 +0100
+++ apache-1.3.29-2/src/modules/proxy/proxy_http.c	2003-12-10 01:12:51.000000000 +0100
@@ -170,6 +170,9 @@
     const char *datestr, *urlstr;
     int result, major, minor;
     const char *content_length;
+#ifdef EAPI
+    char *peer;
+#endif
 
     void *sconf = r->server->module_config;
     proxy_server_conf *conf =
@@ -191,6 +194,12 @@
         return HTTP_BAD_REQUEST;
     urlptr += 3;
     destport = DEFAULT_HTTP_PORT;
+#ifdef EAPI
+    ap_hook_use("ap::mod_proxy::http::handler::set_destport", 
+                AP_HOOK_SIG2(int,ptr), 
+                AP_HOOK_TOPMOST,
+                &destport, r);
+#endif /* EAPI */
     strp = strchr(urlptr, '/');
     if (strp == NULL) {
         desthost = ap_pstrdup(p, urlptr);
@@ -228,12 +237,18 @@
         err = ap_proxy_host2addr(proxyhost, &server_hp);
         if (err != NULL)
             return DECLINED;    /* try another */
+#ifdef EAPI
+	peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);  
+#endif
     }
     else {
         server.sin_port = htons((unsigned short)destport);
         err = ap_proxy_host2addr(desthost, &server_hp);
         if (err != NULL)
             return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
+#ifdef EAPI
+	peer =  ap_psprintf(p, "%s:%u", desthost, destport);  
+#endif
     }
 
 
@@ -308,14 +323,42 @@
     f = ap_bcreate(p, B_RDWR | B_SOCKET);
     ap_bpushfd(f, sock, sock);
 
+#ifdef EAPI
+    {
+        char *errmsg = NULL;
+        ap_hook_use("ap::mod_proxy::http::handler::new_connection", 
+                    AP_HOOK_SIG4(ptr,ptr,ptr,ptr), 
+                    AP_HOOK_DECLINE(NULL),
+                    &errmsg, r, f, peer);
+        if (errmsg != NULL)
+            return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg);
+    }
+#endif /* EAPI */
+
     ap_hard_timeout("proxy send", r);
     ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.1" CRLF,
               NULL);
+#ifdef EAPI
+    {
+	int rc = DECLINED;
+	ap_hook_use("ap::mod_proxy::http::handler::write_host_header", 
+		    AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr), 
+		    AP_HOOK_DECLINE(DECLINED),
+		    &rc, r, f, desthost, destport, destportstr);
+        if (rc == DECLINED) {
+	    if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
+		ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
+	    else
+		ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
+        }
+    }
+#else /* EAPI */
     /* Send Host: now, adding it to req_hdrs wouldn't be much better */
     if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
         ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
     else
         ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
+#endif /* EAPI */
 
     if (conf->viaopt == via_block) {
         /* Block all outgoing Via: headers */
diff -urN apache_1.3.29/src/modules/standard/Makefile.Cygwin apache-1.3.29-2/src/modules/standard/Makefile.Cygwin
--- apache_1.3.29/src/modules/standard/Makefile.Cygwin	2002-01-17 14:20:51.000000000 +0100
+++ apache-1.3.29-2/src/modules/standard/Makefile.Cygwin	2003-12-10 01:36:12.000000000 +0100
@@ -42,7 +42,7 @@
 	else \
         if [ ! -f "$(SRCDIR)/$(SHCORE_IMPLIB).$$" ]; then \
 	      echo "+--------------------------------------------------------+"; \
-		  echo "| There is no shared core 'libhttpd.dll' available!      |"; \
+		  echo "| There is no shared core 'cyghttpd.dll' available!      |"; \
 		  echo "|                                                        |"; \
 		  echo "| This is obviously your first 'make' run with configure |"; \
 		  echo "| flag SHARED_CORE enabled and shared modules.           |"; \
diff -urN apache_1.3.29/src/modules/standard/mod_log_config.c apache-1.3.29-2/src/modules/standard/mod_log_config.c
--- apache_1.3.29/src/modules/standard/mod_log_config.c	2003-02-03 18:13:28.000000000 +0100
+++ apache-1.3.29-2/src/modules/standard/mod_log_config.c	2003-12-10 01:12:51.000000000 +0100
@@ -262,6 +262,9 @@
 typedef const char *(*item_key_func) (request_rec *, char *);
 
 typedef struct {
+#ifdef EAPI
+    char ch;
+#endif
     item_key_func func;
     char *arg;
     int condition_sense;
@@ -580,15 +583,36 @@
     }
 };
 
+#ifdef EAPI
+static struct log_item_list *find_log_func(pool *p, char k)
+#else /* EAPI */
 static struct log_item_list *find_log_func(char k)
+#endif /* EAPI */
 {
     int i;
+#ifdef EAPI
+    struct log_item_list *lil;
+#endif /* EAPI */
 
     for (i = 0; log_item_keys[i].ch; ++i)
         if (k == log_item_keys[i].ch) {
             return &log_item_keys[i];
         }
 
+#ifdef EAPI
+    if (ap_hook_status(ap_psprintf(p, "ap::mod_log_config::log_%c", k)) 
+        != AP_HOOK_STATE_NOTEXISTANT) {
+        lil = (struct log_item_list *)
+              ap_pcalloc(p, sizeof(struct log_item_list));
+        if (lil == NULL)
+            return NULL;
+        lil->ch = k;
+        lil->func = NULL;
+        lil->want_orig_default = 0;
+        return lil;
+    }
+#endif /* EAPI */
+
     return NULL;
 }
 
@@ -714,7 +738,11 @@
             break;
 
         default:
+#ifdef EAPI
+            l = find_log_func(p, *s++);
+#else /* EAPI */
             l = find_log_func(*s++);
+#endif /* EAPI */
             if (!l) {
                 char dummy[2];
 
@@ -723,6 +751,9 @@
                 return ap_pstrcat(p, "Unrecognized LogFormat directive %",
                                dummy, NULL);
             }
+#ifdef EAPI
+            it->ch = s[-1];
+#endif
             it->func = l->func;
             if (it->want_orig == -1) {
                 it->want_orig = l->want_orig_default;
@@ -784,6 +815,15 @@
 
     /* We do.  Do it... */
 
+#ifdef EAPI
+    if (item->func == NULL) {
+        cp = NULL;
+        ap_hook_use(ap_psprintf(r->pool, "ap::mod_log_config::log_%c", item->ch),
+                    AP_HOOK_SIG3(ptr,ptr,ptr), AP_HOOK_DECLINE(NULL),
+                    &cp, r, item->arg);
+    }
+    else
+#endif
     cp = (*item->func) (item->want_orig ? orig : r, item->arg);
     return cp ? cp : "-";
 }
diff -urN apache_1.3.29/src/modules/standard/mod_rewrite.c apache-1.3.29-2/src/modules/standard/mod_rewrite.c
--- apache_1.3.29/src/modules/standard/mod_rewrite.c	2003-10-24 18:11:41.000000000 +0200
+++ apache-1.3.29-2/src/modules/standard/mod_rewrite.c	2003-12-10 01:12:51.000000000 +0100
@@ -3882,6 +3882,15 @@
     }
 #endif /* ndef WIN32 && NETWARE*/
 
+#ifdef EAPI
+    else {
+        ap_hook_use("ap::mod_rewrite::lookup_variable",
+                    AP_HOOK_SIG3(ptr,ptr,ptr), 
+                    AP_HOOK_DECLINE(NULL),
+                    &result, r, var);
+    }
+#endif
+
     if (result == NULL) {
         return ap_pstrdup(r->pool, "");
     }
diff -urN apache_1.3.29/src/modules/standard/mod_so.c apache-1.3.29-2/src/modules/standard/mod_so.c
--- apache_1.3.29/src/modules/standard/mod_so.c	2003-02-03 18:13:29.000000000 +0100
+++ apache-1.3.29-2/src/modules/standard/mod_so.c	2003-12-10 01:12:51.000000000 +0100
@@ -269,11 +269,24 @@
      * Make sure the found module structure is really a module structure
      * 
      */
+#ifdef EAPI
+    if (   modp->magic != MODULE_MAGIC_COOKIE_AP13 
+        && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
+#else
     if (modp->magic != MODULE_MAGIC_COOKIE) {
+#endif
         return ap_pstrcat(cmd->pool, "API module structure `", modname,
                           "' in file ", szModuleFile, " is garbled -"
                           " perhaps this is not an Apache module DSO?", NULL);
     }
+#ifdef EAPI
+    if (modp->magic == MODULE_MAGIC_COOKIE_AP13) {
+        ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, NULL,
+                     "Loaded DSO %s uses plain Apache 1.3 API, "
+                     "this module might crash under EAPI! "
+                     "(please recompile it with -DEAPI)", filename);
+    }
+#endif
 
     /* 
      * Add this module to the Apache core structures
diff -urN apache_1.3.29/src/modules/standard/mod_status.c apache-1.3.29-2/src/modules/standard/mod_status.c
--- apache_1.3.29/src/modules/standard/mod_status.c	2003-02-03 18:13:29.000000000 +0100
+++ apache-1.3.29-2/src/modules/standard/mod_status.c	2003-12-10 01:12:51.000000000 +0100
@@ -694,12 +694,23 @@
 			    ap_rprintf(r,
 			     "<td>?<td nowrap>?<td nowrap>..reading.. </tr>\n\n");
 			else
+#ifndef NO_PRETTYPRINT
+			    ap_rprintf(r,
+			     "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
+			     "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
+			     "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
+			     "</tr>\n\n",
+			     score_record.client,
+			     vhost ? vhost->server_hostname : "(unavailable)",
+			     ap_escape_html(r->pool, score_record.request));
+#else
 			    ap_rprintf(r,
 			     "<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
 			     ap_escape_html(r->pool, score_record.client),
 			     vhost ? ap_escape_html(r->pool, 
 				vhost->server_hostname) : "(unavailable)",
 			     ap_escape_html(r->pool, score_record.request));
+#endif
 		    }		/* no_table_report */
 		}			/* !short_report */
 	    }			/* if (<active child>) */
diff -urN apache_1.3.29/src/os/cygwin/Makefile.tmpl apache-1.3.29-2/src/os/cygwin/Makefile.tmpl
--- apache_1.3.29/src/os/cygwin/Makefile.tmpl	2001-04-02 11:22:10.000000000 +0200
+++ apache-1.3.29-2/src/os/cygwin/Makefile.tmpl	2004-02-09 18:56:06.824148800 +0100
@@ -3,7 +3,7 @@
 INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES)
 LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS)
 
-OBJS=	os.o os-inline.o
+OBJS=	os.o os-inline.o util_cygwin.o
 
 LIB=	libos.a
 
@@ -37,6 +37,12 @@
 
 $(OBJS): Makefile
 
+$(INCDIR)/os.h: os.h
+	cp $< $@
+	
+$(INCDIR)/os-inline.c: os-inline.c
+	cp $< $@
+
 # DO NOT REMOVE
 os-inline.o: os-inline.c $(INCDIR)/ap_config.h \
  $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
@@ -44,3 +50,8 @@
 os.o: os.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
  $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
  $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h os.h
+util_cygwin.o: util_cygwin.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(INCDIR)/os.h $(INCDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/hsregex.h $(INCDIR)/ap_alloc.h $(INCDIR)/buff.h \
+ $(INCDIR)/ap.h $(INCDIR)/util_uri.h $(INCDIR)/http_log.h
diff -urN apache_1.3.29/src/os/cygwin/os.h apache-1.3.29-2/src/os/cygwin/os.h
--- apache_1.3.29/src/os/cygwin/os.h	2003-02-03 18:13:32.000000000 +0100
+++ apache-1.3.29-2/src/os/cygwin/os.h	2004-02-09 18:56:06.844177600 +0100
@@ -88,6 +88,10 @@
 #define PLATFORM "Cygwin"
 #endif
 
+/* define that we implement our own ap_os_canonical_filename() to 
+ * circumvent backslash security holes in cygwin path processing. */
+#define HAVE_CANONICAL_FILENAME
+
 /* 
  * Define winsock.h and winsock2.h stuff taken from Win32 API in case we  
  * want to do socket communication in Win32 native way rather then using 
diff -urN apache_1.3.29/src/os/cygwin/util_cygwin.c apache-1.3.29-2/src/os/cygwin/util_cygwin.c
--- apache_1.3.29/src/os/cygwin/util_cygwin.c	1970-01-01 01:00:00.000000000 +0100
+++ apache-1.3.29-2/src/os/cygwin/util_cygwin.c	2004-02-09 18:56:06.864206400 +0100
@@ -0,0 +1,81 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+#include <os.h>
+#include "httpd.h"
+#include "http_log.h"
+
+
+API_EXPORT(char *) ap_os_canonical_filename(pool *pPool, const char *szFile)
+{
+    char *buf;
+    char buf2[MAX_STRING_LEN];
+    int rc, len; 
+    char *pos;
+    
+    len = strlen(szFile);
+    buf = ap_pstrndup(pPool, szFile, len);
+
+    /* Switch backslashes to forward */
+    for (pos=buf; *pos; pos++)
+        if (*pos == '\\')
+            *pos = '/';
+    
+    return ap_pstrdup(pPool, buf);
+}
+
diff -urN apache_1.3.29/src/support/apxs.pl apache-1.3.29-2/src/support/apxs.pl
--- apache_1.3.29/src/support/apxs.pl	2003-02-22 18:06:20.000000000 +0100
+++ apache-1.3.29-2/src/support/apxs.pl	2003-12-10 01:12:51.000000000 +0100
@@ -796,5 +796,11 @@
     NULL,                  /* child_init                          */
     NULL,                  /* child_exit                          */
     NULL                   /* [#0] post read-request              */
+#ifdef EAPI
+   ,NULL,                  /* EAPI: add_module                    */
+    NULL,                  /* EAPI: remove_module                 */
+    NULL,                  /* EAPI: rewrite_command               */
+    NULL                   /* EAPI: new_connection                */
+#endif
 };
 
diff -urN apache_1.3.29/src/support/httpd.exp apache-1.3.29-2/src/support/httpd.exp
--- apache_1.3.29/src/support/httpd.exp	2003-01-17 13:23:10.000000000 +0100
+++ apache-1.3.29-2/src/support/httpd.exp	2003-12-10 01:12:51.000000000 +0100
@@ -429,3 +429,59 @@
 XML_SetUnparsedEntityDeclHandler
 XML_SetUserData
 XML_UseParserAsHandlerArg
+ap_add_config_define
+ap_make_shared_sub_pool
+ap_global_ctx
+ap_ctx_new
+ap_ctx_get
+ap_ctx_set
+ap_hook_init
+ap_hook_kill
+ap_hook_configure
+ap_hook_register_I
+ap_hook_unregister_I
+ap_hook_status
+ap_hook_use
+ap_hook_call
+ap_mm_useable
+ap_MM_create
+ap_MM_permission
+ap_MM_destroy
+ap_MM_lock
+ap_MM_unlock
+ap_MM_malloc
+ap_MM_realloc
+ap_MM_free
+ap_MM_calloc
+ap_MM_strdup
+ap_MM_sizeof
+ap_MM_maxsize
+ap_MM_available
+ap_MM_error
+ap_mm_create
+ap_mm_permission
+ap_mm_destroy
+ap_mm_lock
+ap_mm_unlock
+ap_mm_malloc
+ap_mm_realloc
+ap_mm_free
+ap_mm_calloc
+ap_mm_strdup
+ap_mm_sizeof
+ap_mm_maxsize
+ap_mm_available
+ap_mm_error
+ap_mm_display_info
+ap_mm_core_create
+ap_mm_core_permission
+ap_mm_core_delete
+ap_mm_core_size
+ap_mm_core_lock
+ap_mm_core_unlock
+ap_mm_core_maxsegsize
+ap_mm_core_align2page
+ap_mm_core_align2word
+ap_mm_lib_error_set
+ap_mm_lib_error_get
+ap_mm_lib_version
