]> git.pld-linux.org Git - packages/apache.git/blob - apache-EAPI.patch
d0efc1df22281911c26dc325686edd3a9600f111
[packages/apache.git] / apache-EAPI.patch
1 diff -urN apache_1.3.14.orig/htdocs/manual/mod/directives.html apache_1.3.14/htdocs/manual/mod/directives.html
2 --- apache_1.3.14.orig/htdocs/manual/mod/directives.html        Tue Oct 10 22:23:46 2000
3 +++ apache_1.3.14/htdocs/manual/mod/directives.html     Sat Nov 11 20:59:29 2000
4 @@ -99,6 +99,7 @@
5  <LI><A HREF="mod_autoindex.html#defaulticon">DefaultIcon</A>
6  <LI><A HREF="mod_mime.html#defaultlanguage">DefaultLanguage</A>
7  <LI><A HREF="core.html#defaulttype">DefaultType</A>
8 +<LI><A HREF="mod_define.html#define">Define</A>
9  <LI><A HREF="mod_access.html#deny">Deny</A>
10  <LI><A HREF="core.html#directory">&lt;Directory&gt;</A>
11  <LI><A HREF="core.html#directorymatch">&lt;DirectoryMatch&gt;</A>
12 diff -urN apache_1.3.14.orig/htdocs/manual/mod/index.html apache_1.3.14/htdocs/manual/mod/index.html
13 --- apache_1.3.14.orig/htdocs/manual/mod/index.html     Tue Oct 10 22:23:46 2000
14 +++ apache_1.3.14/htdocs/manual/mod/index.html  Sat Nov 11 20:58:35 2000
15 @@ -65,6 +65,8 @@
16  <DT><A HREF="mod_cookies.html">mod_cookies</A> up to Apache 1.1.1
17  <DD>Support for Netscape-like cookies.  Replaced in Apache 1.2 by
18  mod_usertrack
19 +<DT><A HREF="mod_define.html">mod_define</A>
20 +<DD>Variable Definition for Arbitrary Directives
21  <DT><A HREF="mod_digest.html">mod_digest</A> Apache 1.1 and up
22  <DD>MD5 authentication
23  <DT><A HREF="mod_dir.html">mod_dir</A>
24 diff -urN apache_1.3.14.orig/htdocs/manual/mod/mod_define.html apache_1.3.14/htdocs/manual/mod/mod_define.html
25 --- apache_1.3.14.orig/htdocs/manual/mod/mod_define.html        Thu Jan  1 01:00:00 1970
26 +++ apache_1.3.14/htdocs/manual/mod/mod_define.html     Sat Nov 11 20:49:14 2000
27 @@ -0,0 +1,135 @@
28 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
29 +<!--%hypertext -->
30 +<!-- mod_define.html                                  -->
31 +<!-- Documentation for the mod_define Apache module   -->
32 +<HTML>
33 +<HEAD>
34 +<TITLE>Apache module mod_define</TITLE>
35 +</HEAD>
36 +
37 +<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
38 +<BODY
39 + BGCOLOR="#FFFFFF"
40 + TEXT="#000000"
41 + LINK="#0000FF"
42 + VLINK="#000080"
43 + ALINK="#FF0000"
44 +>
45 +<BLOCKQUOTE><!-- page indentation -->
46 +<!--#include virtual="header.html" -->
47 +
48 +<BR>
49 +<H1 ALIGN="CENTER">Module mod_define</H1>
50 +<H2 ALIGN="CENTER">Variable Definition For Arbitrary Directives</H2>
51 +
52 +This module is contained in the <CODE>mod_define.c</CODE> file.  It provides
53 +the definition variables for arbitrary directives, i.e. variables which can be
54 +expanded on any(!) directive line. It needs Extended API (EAPI). It is not
55 +compiled into the server by default. To use <CODE>mod_define</CODE> you have
56 +to enable the following line in the server build <CODE>Configuration</CODE>
57 +file:
58 +
59 +<P>
60 +<PRE>
61 +    AddModule  modules/extra/mod_define.o
62 +</PRE>
63 +
64 +<P>
65 +<HR NOSHADE SIZE=1>
66 +
67 +<H3><A NAME="Define">Define</A></H3>
68 +<A
69 + HREF="directive-dict.html#Syntax"
70 + REL="Help"
71 +><STRONG>Syntax:</STRONG></A>
72 +    <CODE>Define</CODE> <EM>variable</EM> <EM>value</EM><BR>
73 +<A
74 + HREF="directive-dict.html#Default"
75 + REL="Help"
76 +><STRONG>Default:</STRONG></A>
77 +    <EM>none</EM><BR>
78 +<A
79 + HREF="directive-dict.html#Context"
80 + REL="Help"
81 +><STRONG>Context:</STRONG></A>
82 +    server config, virtual host, directory, .htaccess<BR>
83 +<A
84 + HREF="directive-dict.html#Override"
85 + REL="Help"
86 +><STRONG>Override:</STRONG></A> none<BR>
87 +<A
88 + HREF="directive-dict.html#Status"
89 + REL="Help"
90 +><STRONG>Status:</STRONG></A> Extension<BR>
91 +<A
92 + HREF="directive-dict.html#Module"
93 + REL="Help"
94 +><STRONG>Module:</STRONG></A> mod_define.c<BR>
95 +<A
96 + HREF="directive-dict.html#Compatibility"
97 + REL="Help"
98 +><STRONG>Compatibility:</STRONG></A> Apache+EAPI<BR>
99 +
100 +<P>
101 +The <CODE>Define</CODE> directive defines a variable which later can be
102 +expanded with the unsafe but short construct
103 +``<CODE>$</CODE><EM>variable</EM>'' or the safe but longer construct
104 +``<CODE>${</CODE><EM>variable</EM><CODE>}</CODE>'' on any configuration line.
105 +Do not intermix this with the third-party module <CODE>mod_macro</CODE>. The
106 +<CODE>mod_define</CODE> module doesn't provide a general macro mechanism,
107 +although one can consider variable substitutions as a special form of macros.
108 +Because the value of to which ``<CODE>$</CODE><EM>variable</EM>'' expands has
109 +to fit into one line. When you need macros which can span more lines, you've
110 +to use <CODE>mod_macro</CODE>. OTOH <CODE>mod_macro</CODE> cannot be used to
111 +expand a variable/macro on an arbitrary directive line.  So, the typical use
112 +case of <CODE>mod_define</CODE> is to make strings <EM>variable</EM> (and this
113 +way easily changeable at one location) and not to <EM>bundle</EM> things
114 +together (as it's the typical use case for macros).
115 +
116 +<P>
117 +The syntax of the expansion construct (
118 +``<CODE>${</CODE><EM>variable</EM><CODE>}</CODE>'') follows the Perl and Shell
119 +syntax, but can be changed via the <CODE>Define</CODE> directive, too. Four
120 +internal variables can be used for this. The default is:
121 +
122 +<BLOCKQUOTE>
123 +<PRE>
124 +Define mod_define::escape "\\"
125 +Define mod_define::dollar "$"
126 +Define mod_define::open   "{"
127 +Define mod_define::close  "}"
128 +</PRE>
129 +</BLOCKQUOTE>
130 +
131 +<P>
132 +When you need to escape some of the expansion constructs you place the
133 +mod_define::escape character in front of it.  The default is the backslash as
134 +in Perl or the Shell.
135 +
136 +<P>
137 +<STRONG>Example:</STRONG>
138 +<BLOCKQUOTE>
139 +<PRE>
140 +Define master     "Joe Average &lt;joe@average.dom&gt;"
141 +Define docroot    /usr/local/apache/htdocs
142 +Define hostname   foo
143 +Define domainname bar.dom
144 +Define portnumber 80
145 +  :
146 +&lt;VirtualHost $hostname.$domainname:$portnumber&gt;
147 +SetEnv       SERVER_MASTER "$master"
148 +ServerName   $hostname.$domainname
149 +ServerAlias  $hostname
150 +Port         $portnumber
151 +DocumentRoot $docroot
152 +&lt;Directory $docroot&gt;
153 +  :
154 +&lt;Directory&gt;
155 +</PRE>
156 +</BLOCKQUOTE>
157 +
158 +<!--#include virtual="footer.html" -->
159 +</BLOCKQUOTE><!-- page indentation -->
160 +</BODY>
161 +</HTML>
162 +<!--/%hypertext -->
163 diff -urN apache_1.3.14.orig/src/ApacheCore.def apache_1.3.14/src/ApacheCore.def
164 --- apache_1.3.14.orig/src/ApacheCore.def       Sun Oct  8 07:23:15 2000
165 +++ apache_1.3.14/src/ApacheCore.def    Sat Nov 11 20:56:47 2000
166 @@ -389,3 +389,18 @@
167         ap_stripprefix @380
168          ap_os_dso_load @381
169          ap_os_dso_error @382
170 +
171 +       ; EAPI patch
172 +       ap_add_config_define   @383
173 +       ap_global_ctx   @384
174 +       ap_ctx_new   @385
175 +       ap_ctx_get   @386
176 +       ap_ctx_set   @387
177 +       ap_hook_init   @388
178 +       ap_hook_kill   @389
179 +       ap_hook_configure   @390
180 +       ap_hook_register_I   @391
181 +       ap_hook_unregister_I   @392
182 +       ap_hook_status   @393
183 +       ap_hook_use   @394
184 +       ap_hook_call   @395
185 diff -urN apache_1.3.14.orig/src/Configuration.tmpl apache_1.3.14/src/Configuration.tmpl
186 --- apache_1.3.14.orig/src/Configuration.tmpl   Sat Aug 14 10:35:43 1999
187 +++ apache_1.3.14/src/Configuration.tmpl        Sat Nov 11 20:49:14 2000
188 @@ -68,6 +68,24 @@
189  #TARGET=
190  
191  ################################################################
192 +# Extended API (EAPI) support:
193 +#
194 +# EAPI:
195 +#   The EAPI rule enables more module hooks, a generic low-level hook
196 +#   mechanism, a generic context mechanism and shared memory based pools. 
197 +#
198 +# EAPI_MM:
199 +#   Set the EAPI_MM variable to either the directory of a MM Shared Memory
200 +#   Library source tree or the installation tree of MM. Alternatively you can
201 +#   also use the value 'SYSTEM' which then indicates that MM is installed
202 +#   under various system locations. When the MM library files cannot be found
203 +#   the EAPI still can be built, but without shared memory pool support, of
204 +#   course.
205 +
206 +Rule EAPI=no
207 +#EAPI_MM=SYSTEM
208 +
209 +################################################################
210  # Dynamic Shared Object (DSO) support
211  #
212  # There is experimental support for compiling the Apache core and
213 @@ -242,6 +260,11 @@
214  ## it does not do per-request stuff.
215  
216  AddModule modules/standard/mod_env.o
217 +
218 +## mod_define expands variables on arbitrary directive lines.
219 +## It requires Extended API (EAPI).
220 +
221 +# AddModule modules/extra/mod_define.o
222  
223  ##
224  ## Request logging modules
225 diff -urN apache_1.3.14.orig/src/Configure apache_1.3.14/src/Configure
226 --- apache_1.3.14.orig/src/Configure    Tue Oct 10 17:30:03 2000
227 +++ apache_1.3.14/src/Configure Sat Nov 11 20:49:14 2000
228 @@ -1778,6 +1778,72 @@
229  fi
230  
231  ####################################################################
232 +## Extended API (EAPI) support:
233 +##
234 +if [ "x$RULE_EAPI" = "x" ]; then
235 +    RULE_EAPI=`./helpers/CutRule EAPI $file`
236 +fi
237 +if [ "x$RULE_EAPI" = "xyes" ]; then
238 +    echo " + enabling Extended API (EAPI)"
239 +    CFLAGS="$CFLAGS -DEAPI"
240 +    #   some vendor compilers are too restrictive
241 +    #   for our ap_hook and ap_ctx sources.
242 +    case "$OS:$CC" in
243 +        *IRIX-32*:*/cc|*IRIX-32*:cc )
244 +            CFLAGS="$CFLAGS -woff 1048,1110,1164"
245 +            ;;
246 +    esac
247 +    #   MM Shared Memory Library support for EAPI
248 +    if [ "x$EAPI_MM" = "x" ]; then
249 +        EAPI_MM=`egrep '^EAPI_MM=' $file | tail -1 | awk -F= '{print $2}'`
250 +    fi
251 +    if [ "x$EAPI_MM" != "x" ]; then
252 +        case $EAPI_MM in
253 +            SYSTEM|/* ) ;;
254 +            * ) for p in . .. ../..; do
255 +                    if [ -d "$p/$EAPI_MM" ]; then
256 +                        EAPI_MM="`echo $p/$EAPI_MM | sed -e 's;/\./;/;g'`" 
257 +                        break
258 +                    fi
259 +                done
260 +                ;;
261 +        esac
262 +        if [ "x$EAPI_MM" = "xSYSTEM" ]; then
263 +            echo "   using MM library for EAPI: (system-wide)"
264 +            CFLAGS="$CFLAGS -DEAPI_MM"
265 +            __INCLUDES="`mm-config --cflags`"
266 +            if [ "x$__INCLUDES" != "x-I/usr/include" ]; then
267 +                INCLUDES="$INCLUDES $__INCLUDES"
268 +            fi
269 +            LDFLAGS="$LDFLAGS `mm-config --ldflags`"
270 +            LIBS="$LIBS `mm-config --libs`"
271 +        else
272 +            if [ -f "$EAPI_MM/.libs/libmm.a" -a -f "$EAPI_MM/mm.h" ]; then
273 +                echo "   using MM library: $EAPI_MM (source-tree only)"
274 +                case $EAPI_MM in
275 +                    /* ) ;;
276 +                    *  ) EAPI_MM="\$(SRCDIR)/$EAPI_MM" ;;
277 +                esac
278 +                CFLAGS="$CFLAGS -DEAPI_MM"
279 +                INCLUDES="$INCLUDES -I$EAPI_MM"
280 +                LDFLAGS="$LDFLAGS -L$EAPI_MM/.libs"
281 +                LIBS="$LIBS -lmm"
282 +            elif [ -f "$EAPI_MM/bin/mm-config" ]; then
283 +                echo "   using MM library: $EAPI_MM (installed)"
284 +                CFLAGS="$CFLAGS -DEAPI_MM"
285 +                INCLUDES="$INCLUDES `$EAPI_MM/bin/mm-config --cflags`"
286 +                LDFLAGS="$LDFLAGS `$EAPI_MM/bin/mm-config --ldflags`"
287 +                LIBS="$LIBS `$EAPI_MM/bin/mm-config --libs`"
288 +            else
289 +                echo "Configure:Error: Cannot find MM library under $EAPI_MM" 1>&2
290 +                exit 1
291 +            fi
292 +        fi
293 +    fi
294 +fi
295 +
296 +
297 +####################################################################
298  ## Add in the Expat library if needed/wanted.
299  ##
300  if [ -d ./lib/expat-lite/ ]; then
301 diff -urN apache_1.3.14.orig/src/ap/Makefile.tmpl apache_1.3.14/src/ap/Makefile.tmpl
302 --- apache_1.3.14.orig/src/ap/Makefile.tmpl     Fri Jun 23 01:22:21 2000
303 +++ apache_1.3.14/src/ap/Makefile.tmpl  Sat Nov 11 20:49:14 2000
304 @@ -6,7 +6,8 @@
305  LIB=libap.a
306  
307  OBJS=ap_cpystrn.o ap_execve.o ap_fnmatch.o ap_getpass.o ap_md5c.o ap_signal.o \
308 -     ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o
309 +     ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o \
310 +     ap_hook.o ap_ctx.o ap_mm.o
311  
312  .c.o:
313         $(CC) -c $(INCLUDES) $(CFLAGS) $<
314 diff -urN apache_1.3.14.orig/src/ap/ap.mak apache_1.3.14/src/ap/ap.mak
315 --- apache_1.3.14.orig/src/ap/ap.mak    Thu Sep 21 15:57:14 2000
316 +++ apache_1.3.14/src/ap/ap.mak Sat Nov 11 20:50:57 2000
317 @@ -50,6 +50,9 @@
318         -@erase "$(INTDIR)\ap_fnmatch.obj"
319         -@erase "$(INTDIR)\ap_md5c.obj"
320         -@erase "$(INTDIR)\ap_sha1.obj"
321 +       -@erase "$(INTDIR)\ap_hook.obj"
322 +       -@erase "$(INTDIR)\ap_ctx.obj"
323 +       -@erase "$(INTDIR)\ap_mm.obj"
324         -@erase "$(INTDIR)\ap_signal.obj"
325         -@erase "$(INTDIR)\ap_slack.obj"
326         -@erase "$(INTDIR)\ap_snprintf.obj"
327 @@ -109,6 +112,9 @@
328         "$(INTDIR)\ap_fnmatch.obj" \
329         "$(INTDIR)\ap_md5c.obj" \
330         "$(INTDIR)\ap_sha1.obj" \
331 +       "$(INTDIR)\ap_hook.obj" \
332 +       "$(INTDIR)\ap_ctx.obj" \
333 +       "$(INTDIR)\ap_mm.obj" \
334         "$(INTDIR)\ap_signal.obj" \
335         "$(INTDIR)\ap_slack.obj" \
336         "$(INTDIR)\ap_snprintf.obj"
337 @@ -143,6 +149,9 @@
338         -@erase "$(INTDIR)\ap_fnmatch.obj"
339         -@erase "$(INTDIR)\ap_md5c.obj"
340         -@erase "$(INTDIR)\ap_sha1.obj"
341 +       -@erase "$(INTDIR)\ap_hook.obj"
342 +       -@erase "$(INTDIR)\ap_ctx.obj"
343 +       -@erase "$(INTDIR)\ap_mm.obj"
344         -@erase "$(INTDIR)\ap_signal.obj"
345         -@erase "$(INTDIR)\ap_slack.obj"
346         -@erase "$(INTDIR)\ap_snprintf.obj"
347 @@ -202,6 +211,9 @@
348         "$(INTDIR)\ap_fnmatch.obj" \
349         "$(INTDIR)\ap_md5c.obj" \
350         "$(INTDIR)\ap_sha1.obj" \
351 +       "$(INTDIR)\ap_hook.obj" \
352 +       "$(INTDIR)\ap_ctx.obj" \
353 +       "$(INTDIR)\ap_mm.obj" \
354         "$(INTDIR)\ap_signal.obj" \
355         "$(INTDIR)\ap_slack.obj" \
356         "$(INTDIR)\ap_snprintf.obj"
357 diff -urN apache_1.3.14.orig/src/ap/ap_ctx.c apache_1.3.14/src/ap/ap_ctx.c
358 --- apache_1.3.14.orig/src/ap/ap_ctx.c  Thu Jan  1 01:00:00 1970
359 +++ apache_1.3.14/src/ap/ap_ctx.c       Sat Nov 11 20:49:14 2000
360 @@ -0,0 +1,155 @@
361 +/* ====================================================================
362 + * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
363 + *
364 + * Redistribution and use in source and binary forms, with or without
365 + * modification, are permitted provided that the following conditions
366 + * are met:
367 + *
368 + * 1. Redistributions of source code must retain the above copyright
369 + *    notice, this list of conditions and the following disclaimer. 
370 + *
371 + * 2. Redistributions in binary form must reproduce the above copyright
372 + *    notice, this list of conditions and the following disclaimer in
373 + *    the documentation and/or other materials provided with the
374 + *    distribution.
375 + *
376 + * 3. All advertising materials mentioning features or use of this
377 + *    software must display the following acknowledgment:
378 + *    "This product includes software developed by the Apache Group
379 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
380 + *
381 + * 4. The names "Apache Server" and "Apache Group" must not be used to
382 + *    endorse or promote products derived from this software without
383 + *    prior written permission. For written permission, please contact
384 + *    apache@apache.org.
385 + *
386 + * 5. Products derived from this software may not be called "Apache"
387 + *    nor may "Apache" appear in their names without prior written
388 + *    permission of the Apache Group.
389 + *
390 + * 6. Redistributions of any form whatsoever must retain the following
391 + *    acknowledgment:
392 + *    "This product includes software developed by the Apache Group
393 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
394 + *
395 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
396 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
397 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
398 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
399 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
400 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
401 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
402 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
403 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
404 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
405 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
406 + * OF THE POSSIBILITY OF SUCH DAMAGE.
407 + * ====================================================================
408 + *
409 + * This software consists of voluntary contributions made by many
410 + * individuals on behalf of the Apache Group and was originally based
411 + * on public domain software written at the National Center for
412 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
413 + * For more information on the Apache Group and the Apache HTTP server
414 + * project, please see <http://www.apache.org/>.
415 + *
416 + */
417 +
418 +/*
419 +**  Generic Context Interface for Apache
420 +**  Written by Ralf S. Engelschall <rse@engelschall.com> 
421 +*/
422 +
423 +#ifdef EAPI
424 +
425 +#include "httpd.h"
426 +#include "ap_config.h"
427 +#include "ap_ctx.h"
428 +
429 +API_EXPORT(ap_ctx *) ap_ctx_new(pool *p)
430 +{
431 +    ap_ctx *ctx;
432 +    int i;
433 +
434 +    if (p != NULL) {
435 +        ctx = (ap_ctx *)ap_palloc(p, sizeof(ap_ctx_rec));
436 +        ctx->cr_pool = p;
437 +        ctx->cr_entry = (ap_ctx_entry **)
438 +            ap_palloc(p, sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
439 +    }
440 +    else {
441 +        ctx = (ap_ctx *)malloc(sizeof(ap_ctx_rec));
442 +        ctx->cr_pool = NULL;
443 +        ctx->cr_entry = (ap_ctx_entry **)
444 +            malloc(sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
445 +    }
446 +    for (i = 0; i < AP_CTX_MAX_ENTRIES+1; i++) 
447 +        ctx->cr_entry[i] = NULL;
448 +    return ctx;
449 +}
450 +
451 +API_EXPORT(void) ap_ctx_set(ap_ctx *ctx, char *key, void *val)
452 +{
453 +    int i;
454 +    ap_ctx_entry *ce;
455 +
456 +    ce = NULL;
457 +    for (i = 0; ctx->cr_entry[i] != NULL; i++) {
458 +        if (strcmp(ctx->cr_entry[i]->ce_key, key) == 0) {
459 +            ce = ctx->cr_entry[i];
460 +            break;
461 +        }
462 +    }
463 +    if (ce == NULL) {
464 +        if (i == AP_CTX_MAX_ENTRIES)
465 +            return;
466 +        if (ctx->cr_pool != NULL) {
467 +            ce = (ap_ctx_entry *)ap_palloc(ctx->cr_pool, sizeof(ap_ctx_entry));
468 +            ce->ce_key = ap_pstrdup(ctx->cr_pool, key);
469 +        }
470 +        else {
471 +            ce = (ap_ctx_entry *)malloc(sizeof(ap_ctx_entry));
472 +            ce->ce_key = strdup(key);
473 +        }
474 +        ctx->cr_entry[i] = ce;
475 +        ctx->cr_entry[i+1] = NULL;
476 +    }
477 +    ce->ce_val = val;
478 +    return;
479 +}
480 +
481 +API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key)
482 +{
483 +    int i;
484 +
485 +    for (i = 0; ctx->cr_entry[i] != NULL; i++)
486 +        if (strcmp(ctx->cr_entry[i]->ce_key, key) == 0)
487 +            return ctx->cr_entry[i]->ce_val;
488 +    return NULL;
489 +}
490 +
491 +API_EXPORT(ap_ctx *) ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base)
492 +{
493 +    ap_ctx *new;
494 +    int i;
495 +
496 +#ifdef POOL_DEBUG
497 +    if (p != NULL) {
498 +        if (!ap_pool_is_ancestor(over->cr_pool, p))
499 +            ap_log_assert("ap_ctx_overlay: overlay's pool is not an ancestor of p", 
500 +                          __FILE__, __LINE__);
501 +        if (!ap_pool_is_ancestor(base->cr_pool, p))
502 +            ap_log_assert("ap_ctx_overlay: base's pool is not an ancestor of p",
503 +                          __FILE__, __LINE__);
504 +    }
505 +#endif
506 +    if ((new = ap_ctx_new(p)) == NULL)
507 +        return NULL;
508 +    memcpy(new->cr_entry, base->cr_entry, 
509 +           sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
510 +    for (i = 0; over->cr_entry[i] != NULL; i++)
511 +        ap_ctx_set(new, over->cr_entry[i]->ce_key, over->cr_entry[i]->ce_val);
512 +    return new;
513 +}
514 +
515 +#endif /* EAPI */
516 diff -urN apache_1.3.14.orig/src/ap/ap_hook.c apache_1.3.14/src/ap/ap_hook.c
517 --- apache_1.3.14.orig/src/ap/ap_hook.c Thu Jan  1 01:00:00 1970
518 +++ apache_1.3.14/src/ap/ap_hook.c      Sat Nov 11 20:49:14 2000
519 @@ -0,0 +1,930 @@
520 +#if 0
521 +=pod
522 +#endif
523 +/* ====================================================================
524 + * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
525 + *
526 + * Redistribution and use in source and binary forms, with or without
527 + * modification, are permitted provided that the following conditions
528 + * are met:
529 + *
530 + * 1. Redistributions of source code must retain the above copyright
531 + *    notice, this list of conditions and the following disclaimer. 
532 + *
533 + * 2. Redistributions in binary form must reproduce the above copyright
534 + *    notice, this list of conditions and the following disclaimer in
535 + *    the documentation and/or other materials provided with the
536 + *    distribution.
537 + *
538 + * 3. All advertising materials mentioning features or use of this
539 + *    software must display the following acknowledgment:
540 + *    "This product includes software developed by the Apache Group
541 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
542 + *
543 + * 4. The names "Apache Server" and "Apache Group" must not be used to
544 + *    endorse or promote products derived from this software without
545 + *    prior written permission. For written permission, please contact
546 + *    apache@apache.org.
547 + *
548 + * 5. Products derived from this software may not be called "Apache"
549 + *    nor may "Apache" appear in their names without prior written
550 + *    permission of the Apache Group.
551 + *
552 + * 6. Redistributions of any form whatsoever must retain the following
553 + *    acknowledgment:
554 + *    "This product includes software developed by the Apache Group
555 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
556 + *
557 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
558 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
559 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
560 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
561 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
562 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
563 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
564 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
565 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
566 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
567 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
568 + * OF THE POSSIBILITY OF SUCH DAMAGE.
569 + * ====================================================================
570 + *
571 + * This software consists of voluntary contributions made by many
572 + * individuals on behalf of the Apache Group and was originally based
573 + * on public domain software written at the National Center for
574 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
575 + * For more information on the Apache Group and the Apache HTTP server
576 + * project, please see <http://www.apache.org/>.
577 + *
578 + */
579 +
580 +/*
581 +**  Implementation of a Generic Hook Interface for Apache
582 +**  Written by Ralf S. Engelschall <rse@engelschall.com> 
583 +**
584 +**  See POD document at end of ap_hook.h for description.
585 +**  View it with the command ``pod2man ap_hook.h | nroff -man | more''
586 +**
587 +**  Attention: This source file is a little bit tricky.
588 +**             It's a combination of a C source and an embedded Perl script
589 +**             (which updates the C source). The purpose of this is to have
590 +**             both things together at one place. So you can both pass
591 +**             this file to the C compiler and the Perl interpreter.
592 +*/
593 +
594 +                                      /*
595 +                                       * Premature optimization is 
596 +                                       * the root of all evil.
597 +                                       *       -- D. E. Knuth
598 +                                       */
599 +
600 +#ifdef EAPI
601 +
602 +#include "httpd.h"
603 +#include "http_log.h"
604 +#include "ap_config.h"
605 +#include "ap_hook.h"
606 +
607 +/* 
608 + * the internal hook pool
609 + */
610 +static ap_hook_entry **ap_hook_pool = NULL;
611 +
612 +/* 
613 + * forward prototypes for internal functions
614 + */
615 +static int            ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf);
616 +static ap_hook_entry *ap_hook_create(char *hook);
617 +static ap_hook_entry *ap_hook_find(char *hook);
618 +static void           ap_hook_destroy(ap_hook_entry *he);
619 +
620 +/*
621 + * Initialize the hook mechanism
622 + */
623 +API_EXPORT(void) ap_hook_init(void)
624 +{
625 +    int i;
626 +
627 +    if (ap_hook_pool != NULL)
628 +        return;
629 +    ap_hook_pool = (ap_hook_entry **)malloc(sizeof(ap_hook_entry *)
630 +                                            *(AP_HOOK_MAX_ENTRIES+1));
631 +    for (i = 0; i < AP_HOOK_MAX_ENTRIES; i++)
632 +        ap_hook_pool[i] = NULL;
633 +    return;
634 +}
635 +
636 +/*
637 + * Kill the hook mechanism
638 + */
639 +API_EXPORT(void) ap_hook_kill(void)
640 +{
641 +    int i;
642 +
643 +    if (ap_hook_pool == NULL)
644 +        return;
645 +    for (i = 0; ap_hook_pool[i] != NULL; i++)
646 +        ap_hook_destroy(ap_hook_pool[i]);
647 +    free(ap_hook_pool);
648 +    ap_hook_pool = NULL;
649 +    return;
650 +}
651 +    
652 +/*
653 + * Smart creation of a hook (when it exist this is the same as
654 + * ap_hook_find, when it doesn't exists it is created)
655 + */
656 +static ap_hook_entry *ap_hook_create(char *hook)
657 +{
658 +    int i;
659 +    ap_hook_entry *he;
660 +
661 +    for (i = 0; ap_hook_pool[i] != NULL; i++)
662 +        if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
663 +            return ap_hook_pool[i];
664 +
665 +    if (i >= AP_HOOK_MAX_ENTRIES)
666 +        return NULL;
667 +
668 +    if ((he = (ap_hook_entry *)malloc(sizeof(ap_hook_entry))) == NULL)
669 +        return NULL;
670 +    ap_hook_pool[i] = he;
671 +
672 +    he->he_hook          = strdup(hook);
673 +    he->he_sig           = AP_HOOK_SIG_UNKNOWN;
674 +    he->he_modeid        = AP_HOOK_MODE_UNKNOWN;
675 +    he->he_modeval.v_int = 0;
676 +
677 +    he->he_func = (ap_hook_func **)malloc(sizeof(ap_hook_func *)
678 +                                          *(AP_HOOK_MAX_FUNCS+1));
679 +    if (he->he_func == NULL)
680 +        return FALSE;
681 +
682 +    for (i = 0; i < AP_HOOK_MAX_FUNCS; i++)
683 +        he->he_func[i] = NULL;
684 +    return he;
685 +}
686 +
687 +/*
688 + * Find a particular hook
689 + */
690 +static ap_hook_entry *ap_hook_find(char *hook)
691 +{
692 +    int i;
693 +
694 +    for (i = 0; ap_hook_pool[i] != NULL; i++)
695 +        if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
696 +            return ap_hook_pool[i];
697 +    return NULL;
698 +}
699 +
700 +/*
701 + * Destroy a particular hook
702 + */
703 +static void ap_hook_destroy(ap_hook_entry *he)
704 +{
705 +    int i;
706 +
707 +    if (he == NULL)
708 +        return;
709 +    free(he->he_hook);
710 +    for (i = 0; he->he_func[i] != NULL; i++)
711 +        free(he->he_func[i]);
712 +    free(he->he_func);
713 +    free(he);
714 +    return;
715 +}
716 +
717 +/*
718 + * Configure a particular hook, 
719 + * i.e. remember its signature and return value mode
720 + */
721 +API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
722 +{
723 +    ap_hook_entry *he;
724 +    va_list ap;
725 +    int rc;
726 +
727 +    va_start(ap, modeid);
728 +    if ((he = ap_hook_create(hook)) == NULL)
729 +        rc = FALSE;
730 +    else {
731 +        he->he_sig = sig;
732 +        he->he_modeid = modeid;
733 +        if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) {
734 +            if (AP_HOOK_SIG_HAS(sig, RC, char))
735 +                he->he_modeval.v_char = va_arg(ap, va_type(char));
736 +            else if (AP_HOOK_SIG_HAS(sig, RC, int))
737 +                he->he_modeval.v_int = va_arg(ap, va_type(int));
738 +            else if (AP_HOOK_SIG_HAS(sig, RC, long))
739 +                he->he_modeval.v_long = va_arg(ap, va_type(long));
740 +            else if (AP_HOOK_SIG_HAS(sig, RC, float))
741 +                he->he_modeval.v_float = va_arg(ap, va_type(float));
742 +            else if (AP_HOOK_SIG_HAS(sig, RC, double))
743 +                he->he_modeval.v_double = va_arg(ap, va_type(double));
744 +            else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
745 +                he->he_modeval.v_ptr = va_arg(ap, va_type(ptr));
746 +        }
747 +        rc = TRUE;
748 +    }
749 +    va_end(ap);
750 +    return rc;
751 +}
752 +
753 +/*
754 + * Register a function to call for a hook
755 + */
756 +API_EXPORT(int) ap_hook_register_I(char *hook, void *func, void *ctx)
757 +{
758 +    int i, j;
759 +    ap_hook_entry *he;
760 +    ap_hook_func *hf;
761 +
762 +    if ((he = ap_hook_create(hook)) == NULL)
763 +        return FALSE;
764 +
765 +    for (i = 0; he->he_func[i] != NULL; i++)
766 +        if (he->he_func[i]->hf_ptr == func)
767 +            return FALSE;
768 +
769 +    if (i == AP_HOOK_MAX_FUNCS)
770 +        return FALSE;
771 +
772 +    if ((hf = (ap_hook_func *)malloc(sizeof(ap_hook_func))) == NULL)
773 +        return FALSE;
774 +
775 +    for (j = i; j >= 0; j--)
776 +        he->he_func[j+1] = he->he_func[j];
777 +    he->he_func[0] = hf;
778 +
779 +    hf->hf_ptr = func;
780 +    hf->hf_ctx = ctx;
781 +
782 +    return TRUE;
783 +}
784 +
785 +/*
786 + * Unregister a function to call for a hook
787 + */
788 +API_EXPORT(int) ap_hook_unregister_I(char *hook, void *func)
789 +{
790 +    int i, j;
791 +    ap_hook_entry *he;
792 +
793 +    if ((he = ap_hook_find(hook)) == NULL)
794 +        return FALSE;
795 +    for (i = 0; he->he_func[i] != NULL; i++) {
796 +        if (he->he_func[i]->hf_ptr == func) {
797 +            free(he->he_func[i]);
798 +            for (j = i; he->he_func[j] != NULL; j++)
799 +                he->he_func[j] = he->he_func[j+1];
800 +            return TRUE;
801 +        }
802 +    }
803 +    return FALSE;
804 +}
805 +
806 +/*
807 + * Retrieve the status of a particular hook
808 + */
809 +API_EXPORT(ap_hook_state) ap_hook_status(char *hook)
810 +{
811 +    ap_hook_entry *he;
812 +
813 +    if ((he = ap_hook_find(hook)) == NULL)
814 +        return AP_HOOK_STATE_NOTEXISTANT;
815 +    if (   he->he_func[0] != NULL 
816 +        && he->he_sig != AP_HOOK_SIG_UNKNOWN
817 +        && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
818 +        return AP_HOOK_STATE_REGISTERED;
819 +    if (   he->he_sig != AP_HOOK_SIG_UNKNOWN 
820 +        && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
821 +        return AP_HOOK_STATE_CONFIGURED;
822 +    return AP_HOOK_STATE_ESTABLISHED;
823 +}
824 +
825 +/*
826 + * Use a hook, i.e. optional on-the-fly configure it before calling it
827 + */
828 +API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
829 +{
830 +    int i;
831 +    ap_hook_value modeval;
832 +    ap_hook_entry *he;
833 +    va_list ap;
834 +    int rc;
835 +
836 +    va_start(ap, modeid);
837 +
838 +    if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) {
839 +        if (AP_HOOK_SIG_HAS(sig, RC, char))
840 +            modeval.v_char = va_arg(ap, va_type(char));
841 +        else if (AP_HOOK_SIG_HAS(sig, RC, int))
842 +            modeval.v_int = va_arg(ap, va_type(int));
843 +        else if (AP_HOOK_SIG_HAS(sig, RC, long))
844 +            modeval.v_long = va_arg(ap, va_type(long));
845 +        else if (AP_HOOK_SIG_HAS(sig, RC, float))
846 +            modeval.v_float = va_arg(ap, va_type(float));
847 +        else if (AP_HOOK_SIG_HAS(sig, RC, double))
848 +            modeval.v_double = va_arg(ap, va_type(double));
849 +        else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
850 +            modeval.v_ptr = va_arg(ap, va_type(ptr));
851 +    }
852 +
853 +    if ((he = ap_hook_create(hook)) == NULL)
854 +        return FALSE;
855 +
856 +    if (he->he_sig == AP_HOOK_SIG_UNKNOWN)
857 +        he->he_sig = sig;
858 +    if (he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
859 +        he->he_modeid  = modeid;
860 +        he->he_modeval = modeval;
861 +    }
862 +
863 +    for (i = 0; he->he_func[i] != NULL; i++)
864 +        if (ap_hook_call_func(ap, he, he->he_func[i]))
865 +            break;
866 +
867 +    if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
868 +        rc = TRUE;
869 +    else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
870 +        rc = FALSE;
871 +    else
872 +        rc = TRUE;
873 +
874 +    va_end(ap);
875 +    return rc;
876 +}
877 +
878 +/*
879 + * Call a hook
880 + */
881 +API_EXPORT(int) ap_hook_call(char *hook, ...)
882 +{
883 +    int i;
884 +    ap_hook_entry *he;
885 +    va_list ap;
886 +    int rc;
887 +    
888 +    va_start(ap, hook);
889 +
890 +    if ((he = ap_hook_find(hook)) == NULL) {
891 +        va_end(ap);
892 +        return FALSE;
893 +    }
894 +    if (   he->he_sig == AP_HOOK_SIG_UNKNOWN
895 +        || he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
896 +        va_end(ap);
897 +        return FALSE;
898 +    }
899 +
900 +    for (i = 0; he->he_func[i] != NULL; i++)
901 +        if (ap_hook_call_func(ap, he, he->he_func[i]))
902 +            break;
903 +
904 +    if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
905 +        rc = TRUE;
906 +    else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
907 +        rc = FALSE;
908 +    else
909 +        rc = TRUE;
910 +
911 +    va_end(ap);
912 +    return rc;
913 +}
914 +
915 +static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf)
916 +{
917 +    void *v_rc;
918 +    ap_hook_value v_tmp;
919 +    int rc;
920 +
921 +    /*
922 +     * Now we dispatch the various function calls. We support function
923 +     * signatures with up to 9 types (1 return type, 8 argument types) where
924 +     * each argument can have 7 different types (ctx, char, int, long, float,
925 +     * double, ptr), so theoretically there are 9^7 (=4782969) combinations
926 +     * possible.  But because we don't need all of them, of course, we
927 +     * implement only the following well chosen subset (duplicates are ok):
928 +     *
929 +     * 1. `The basic hook'.
930 +     *
931 +     *    void func()
932 +     *
933 +     * 2. The standard set of signatures which form all combinations of
934 +     *    int&ptr based signatures for up to 3 arguments. We provide
935 +     *    them per default for module authors.
936 +     *
937 +     *    int func()
938 +     *    ptr func()
939 +     *    int func(int)
940 +     *    int func(ptr)
941 +     *    ptr func(int)
942 +     *    ptr func(ptr)
943 +     *    int func(int,int)
944 +     *    int func(int,ptr)
945 +     *    int func(ptr,int)
946 +     *    int func(ptr,ptr)
947 +     *    ptr func(int,int)
948 +     *    ptr func(int,ptr)
949 +     *    ptr func(ptr,int)
950 +     *    ptr func(ptr,ptr)
951 +     *    int func(int,int,int)
952 +     *    int func(int,int,ptr)
953 +     *    int func(int,ptr,int)
954 +     *    int func(int,ptr,ptr)
955 +     *    int func(ptr,int,int)
956 +     *    int func(ptr,int,ptr)
957 +     *    int func(ptr,ptr,int)
958 +     *    int func(ptr,ptr,ptr)
959 +     *    ptr func(int,int,int)
960 +     *    ptr func(int,int,ptr)
961 +     *    ptr func(int,ptr,int)
962 +     *    ptr func(int,ptr,ptr)
963 +     *    ptr func(ptr,int,int)
964 +     *    ptr func(ptr,int,ptr)
965 +     *    ptr func(ptr,ptr,int)
966 +     *    ptr func(ptr,ptr,ptr)
967 +     *
968 +     * 3. Actually currently used hooks.
969 +     *
970 +     *    int   func(ptr)                          [2x]
971 +     *    int   func(ptr,ptr)                      [2x]
972 +     *    int   func(ptr,ptr,int)                  [5x]
973 +     *    int   func(ptr,ptr,ptr,int)              [1x]
974 +     *    int   func(ptr,ptr,ptr,int,ptr)          [1x]
975 +     *    int   func(ptr,ptr,ptr,ptr,int)          [1x]
976 +     *    int   func(ptr,ptr,ptr,ptr,int,ptr)      [1x]
977 +     *    ptr   func(ptr,ptr)                      [3x]
978 +     *    ptr   func(ptr,ptr,ptr,ptr,ptr)          [1x]
979 +     *    void  func(ptr)                          [2x]
980 +     *    void  func(ptr,int,int)                  [1x]
981 +     *    void  func(ptr,ptr)                      [5x]
982 +     *    void  func(ptr,ptr,ptr)                  [3x]
983 +     *    void  func(ptr,ptr,ptr,ptr)              [2x]
984 +     *
985 +     * To simplify the programming task we generate the actual dispatch code
986 +     * for these calls via the embedded Perl script at the end of this source
987 +     * file. This script parses the above lines and generates the section
988 +     * below.  So, when you need more signature variants just add them to the
989 +     * above list and run
990 +     *
991 +     *     $ perl ap_hook.c
992 +     *
993 +     * This automatically updates the above code.
994 +     */
995 +
996 +    rc = TRUE;
997 +    v_rc = NULL;
998 +    if (!AP_HOOK_SIG_HAS(he->he_sig, RC, void)) {
999 +        if (he->he_modeid == AP_HOOK_MODE_DECLTMP) {
1000 +            /* the return variable is a temporary one */ 
1001 +            if (AP_HOOK_SIG_HAS(he->he_sig, RC, char))
1002 +                v_rc = &v_tmp.v_char;
1003 +            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, int))
1004 +                v_rc = &v_tmp.v_int;
1005 +            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, long))
1006 +                v_rc = &v_tmp.v_long;
1007 +            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, float))
1008 +                v_rc = &v_tmp.v_float;
1009 +            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, double))
1010 +                v_rc = &v_tmp.v_double;
1011 +            else if (AP_HOOK_SIG_HAS(he->he_sig, RC, ptr))
1012 +                v_rc = &v_tmp.v_ptr;
1013 +        }
1014 +        else {
1015 +            /* the return variable is provided by caller */ 
1016 +            v_rc = va_arg(ap, void *);
1017 +        }
1018 +    }
1019 +
1020 +    /* ----BEGIN GENERATED SECTION-------- */
1021 +    if (he->he_sig == AP_HOOK_SIG1(void)) {
1022 +        /* Call: void func() */
1023 +        ((void(*)())(hf->hf_ptr))();
1024 +    }
1025 +    else if (he->he_sig == AP_HOOK_SIG1(int)) {
1026 +        /* Call: int func() */
1027 +        *((int *)v_rc) = ((int(*)())(hf->hf_ptr))();
1028 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1029 +    }
1030 +    else if (he->he_sig == AP_HOOK_SIG1(ptr)) {
1031 +        /* Call: ptr func() */
1032 +        *((void * *)v_rc) = ((void *(*)())(hf->hf_ptr))();
1033 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1034 +    }
1035 +    else if (he->he_sig == AP_HOOK_SIG2(int, int)) {
1036 +        /* Call: int func(int) */
1037 +        int   v1 = va_arg(ap, va_type(int));
1038 +        *((int *)v_rc) = ((int(*)(int))(hf->hf_ptr))(v1);
1039 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1040 +    }
1041 +    else if (he->he_sig == AP_HOOK_SIG2(int, ptr)) {
1042 +        /* Call: int func(ptr) */
1043 +        void *v1 = va_arg(ap, va_type(ptr));
1044 +        *((int *)v_rc) = ((int(*)(void *))(hf->hf_ptr))(v1);
1045 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1046 +    }
1047 +    else if (he->he_sig == AP_HOOK_SIG2(ptr, int)) {
1048 +        /* Call: ptr func(int) */
1049 +        int   v1 = va_arg(ap, va_type(int));
1050 +        *((void * *)v_rc) = ((void *(*)(int))(hf->hf_ptr))(v1);
1051 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1052 +    }
1053 +    else if (he->he_sig == AP_HOOK_SIG2(ptr, ptr)) {
1054 +        /* Call: ptr func(ptr) */
1055 +        void *v1 = va_arg(ap, va_type(ptr));
1056 +        *((void * *)v_rc) = ((void *(*)(void *))(hf->hf_ptr))(v1);
1057 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1058 +    }
1059 +    else if (he->he_sig == AP_HOOK_SIG3(int, int, int)) {
1060 +        /* Call: int func(int,int) */
1061 +        int   v1 = va_arg(ap, va_type(int));
1062 +        int   v2 = va_arg(ap, va_type(int));
1063 +        *((int *)v_rc) = ((int(*)(int, int))(hf->hf_ptr))(v1, v2);
1064 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1065 +    }
1066 +    else if (he->he_sig == AP_HOOK_SIG3(int, int, ptr)) {
1067 +        /* Call: int func(int,ptr) */
1068 +        int   v1 = va_arg(ap, va_type(int));
1069 +        void *v2 = va_arg(ap, va_type(ptr));
1070 +        *((int *)v_rc) = ((int(*)(int, void *))(hf->hf_ptr))(v1, v2);
1071 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1072 +    }
1073 +    else if (he->he_sig == AP_HOOK_SIG3(int, ptr, int)) {
1074 +        /* Call: int func(ptr,int) */
1075 +        void *v1 = va_arg(ap, va_type(ptr));
1076 +        int   v2 = va_arg(ap, va_type(int));
1077 +        *((int *)v_rc) = ((int(*)(void *, int))(hf->hf_ptr))(v1, v2);
1078 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1079 +    }
1080 +    else if (he->he_sig == AP_HOOK_SIG3(int, ptr, ptr)) {
1081 +        /* Call: int func(ptr,ptr) */
1082 +        void *v1 = va_arg(ap, va_type(ptr));
1083 +        void *v2 = va_arg(ap, va_type(ptr));
1084 +        *((int *)v_rc) = ((int(*)(void *, void *))(hf->hf_ptr))(v1, v2);
1085 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1086 +    }
1087 +    else if (he->he_sig == AP_HOOK_SIG3(ptr, int, int)) {
1088 +        /* Call: ptr func(int,int) */
1089 +        int   v1 = va_arg(ap, va_type(int));
1090 +        int   v2 = va_arg(ap, va_type(int));
1091 +        *((void * *)v_rc) = ((void *(*)(int, int))(hf->hf_ptr))(v1, v2);
1092 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1093 +    }
1094 +    else if (he->he_sig == AP_HOOK_SIG3(ptr, int, ptr)) {
1095 +        /* Call: ptr func(int,ptr) */
1096 +        int   v1 = va_arg(ap, va_type(int));
1097 +        void *v2 = va_arg(ap, va_type(ptr));
1098 +        *((void * *)v_rc) = ((void *(*)(int, void *))(hf->hf_ptr))(v1, v2);
1099 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1100 +    }
1101 +    else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, int)) {
1102 +        /* Call: ptr func(ptr,int) */
1103 +        void *v1 = va_arg(ap, va_type(ptr));
1104 +        int   v2 = va_arg(ap, va_type(int));
1105 +        *((void * *)v_rc) = ((void *(*)(void *, int))(hf->hf_ptr))(v1, v2);
1106 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1107 +    }
1108 +    else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, ptr)) {
1109 +        /* Call: ptr func(ptr,ptr) */
1110 +        void *v1 = va_arg(ap, va_type(ptr));
1111 +        void *v2 = va_arg(ap, va_type(ptr));
1112 +        *((void * *)v_rc) = ((void *(*)(void *, void *))(hf->hf_ptr))(v1, v2);
1113 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1114 +    }
1115 +    else if (he->he_sig == AP_HOOK_SIG4(int, int, int, int)) {
1116 +        /* Call: int func(int,int,int) */
1117 +        int   v1 = va_arg(ap, va_type(int));
1118 +        int   v2 = va_arg(ap, va_type(int));
1119 +        int   v3 = va_arg(ap, va_type(int));
1120 +        *((int *)v_rc) = ((int(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
1121 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1122 +    }
1123 +    else if (he->he_sig == AP_HOOK_SIG4(int, int, int, ptr)) {
1124 +        /* Call: int func(int,int,ptr) */
1125 +        int   v1 = va_arg(ap, va_type(int));
1126 +        int   v2 = va_arg(ap, va_type(int));
1127 +        void *v3 = va_arg(ap, va_type(ptr));
1128 +        *((int *)v_rc) = ((int(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
1129 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1130 +    }
1131 +    else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, int)) {
1132 +        /* Call: int func(int,ptr,int) */
1133 +        int   v1 = va_arg(ap, va_type(int));
1134 +        void *v2 = va_arg(ap, va_type(ptr));
1135 +        int   v3 = va_arg(ap, va_type(int));
1136 +        *((int *)v_rc) = ((int(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
1137 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1138 +    }
1139 +    else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, ptr)) {
1140 +        /* Call: int func(int,ptr,ptr) */
1141 +        int   v1 = va_arg(ap, va_type(int));
1142 +        void *v2 = va_arg(ap, va_type(ptr));
1143 +        void *v3 = va_arg(ap, va_type(ptr));
1144 +        *((int *)v_rc) = ((int(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
1145 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1146 +    }
1147 +    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, int)) {
1148 +        /* Call: int func(ptr,int,int) */
1149 +        void *v1 = va_arg(ap, va_type(ptr));
1150 +        int   v2 = va_arg(ap, va_type(int));
1151 +        int   v3 = va_arg(ap, va_type(int));
1152 +        *((int *)v_rc) = ((int(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
1153 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1154 +    }
1155 +    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, ptr)) {
1156 +        /* Call: int func(ptr,int,ptr) */
1157 +        void *v1 = va_arg(ap, va_type(ptr));
1158 +        int   v2 = va_arg(ap, va_type(int));
1159 +        void *v3 = va_arg(ap, va_type(ptr));
1160 +        *((int *)v_rc) = ((int(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
1161 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1162 +    }
1163 +    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, int)) {
1164 +        /* Call: int func(ptr,ptr,int) */
1165 +        void *v1 = va_arg(ap, va_type(ptr));
1166 +        void *v2 = va_arg(ap, va_type(ptr));
1167 +        int   v3 = va_arg(ap, va_type(int));
1168 +        *((int *)v_rc) = ((int(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
1169 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1170 +    }
1171 +    else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, ptr)) {
1172 +        /* Call: int func(ptr,ptr,ptr) */
1173 +        void *v1 = va_arg(ap, va_type(ptr));
1174 +        void *v2 = va_arg(ap, va_type(ptr));
1175 +        void *v3 = va_arg(ap, va_type(ptr));
1176 +        *((int *)v_rc) = ((int(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
1177 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1178 +    }
1179 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, int)) {
1180 +        /* Call: ptr func(int,int,int) */
1181 +        int   v1 = va_arg(ap, va_type(int));
1182 +        int   v2 = va_arg(ap, va_type(int));
1183 +        int   v3 = va_arg(ap, va_type(int));
1184 +        *((void * *)v_rc) = ((void *(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
1185 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1186 +    }
1187 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, ptr)) {
1188 +        /* Call: ptr func(int,int,ptr) */
1189 +        int   v1 = va_arg(ap, va_type(int));
1190 +        int   v2 = va_arg(ap, va_type(int));
1191 +        void *v3 = va_arg(ap, va_type(ptr));
1192 +        *((void * *)v_rc) = ((void *(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
1193 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1194 +    }
1195 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, int)) {
1196 +        /* Call: ptr func(int,ptr,int) */
1197 +        int   v1 = va_arg(ap, va_type(int));
1198 +        void *v2 = va_arg(ap, va_type(ptr));
1199 +        int   v3 = va_arg(ap, va_type(int));
1200 +        *((void * *)v_rc) = ((void *(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
1201 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1202 +    }
1203 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, ptr)) {
1204 +        /* Call: ptr func(int,ptr,ptr) */
1205 +        int   v1 = va_arg(ap, va_type(int));
1206 +        void *v2 = va_arg(ap, va_type(ptr));
1207 +        void *v3 = va_arg(ap, va_type(ptr));
1208 +        *((void * *)v_rc) = ((void *(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
1209 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1210 +    }
1211 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, int)) {
1212 +        /* Call: ptr func(ptr,int,int) */
1213 +        void *v1 = va_arg(ap, va_type(ptr));
1214 +        int   v2 = va_arg(ap, va_type(int));
1215 +        int   v3 = va_arg(ap, va_type(int));
1216 +        *((void * *)v_rc) = ((void *(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
1217 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1218 +    }
1219 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, ptr)) {
1220 +        /* Call: ptr func(ptr,int,ptr) */
1221 +        void *v1 = va_arg(ap, va_type(ptr));
1222 +        int   v2 = va_arg(ap, va_type(int));
1223 +        void *v3 = va_arg(ap, va_type(ptr));
1224 +        *((void * *)v_rc) = ((void *(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
1225 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1226 +    }
1227 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, int)) {
1228 +        /* Call: ptr func(ptr,ptr,int) */
1229 +        void *v1 = va_arg(ap, va_type(ptr));
1230 +        void *v2 = va_arg(ap, va_type(ptr));
1231 +        int   v3 = va_arg(ap, va_type(int));
1232 +        *((void * *)v_rc) = ((void *(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
1233 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1234 +    }
1235 +    else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, ptr)) {
1236 +        /* Call: ptr func(ptr,ptr,ptr) */
1237 +        void *v1 = va_arg(ap, va_type(ptr));
1238 +        void *v2 = va_arg(ap, va_type(ptr));
1239 +        void *v3 = va_arg(ap, va_type(ptr));
1240 +        *((void * *)v_rc) = ((void *(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
1241 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1242 +    }
1243 +    else if (he->he_sig == AP_HOOK_SIG5(int, ptr, ptr, ptr, int)) {
1244 +        /* Call: int func(ptr,ptr,ptr,int) */
1245 +        void *v1 = va_arg(ap, va_type(ptr));
1246 +        void *v2 = va_arg(ap, va_type(ptr));
1247 +        void *v3 = va_arg(ap, va_type(ptr));
1248 +        int   v4 = va_arg(ap, va_type(int));
1249 +        *((int *)v_rc) = ((int(*)(void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4);
1250 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1251 +    }
1252 +    else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, int, ptr)) {
1253 +        /* Call: int func(ptr,ptr,ptr,int,ptr) */
1254 +        void *v1 = va_arg(ap, va_type(ptr));
1255 +        void *v2 = va_arg(ap, va_type(ptr));
1256 +        void *v3 = va_arg(ap, va_type(ptr));
1257 +        int   v4 = va_arg(ap, va_type(int));
1258 +        void *v5 = va_arg(ap, va_type(ptr));
1259 +        *((int *)v_rc) = ((int(*)(void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
1260 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1261 +    }
1262 +    else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, ptr, int)) {
1263 +        /* Call: int func(ptr,ptr,ptr,ptr,int) */
1264 +        void *v1 = va_arg(ap, va_type(ptr));
1265 +        void *v2 = va_arg(ap, va_type(ptr));
1266 +        void *v3 = va_arg(ap, va_type(ptr));
1267 +        void *v4 = va_arg(ap, va_type(ptr));
1268 +        int   v5 = va_arg(ap, va_type(int));
1269 +        *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4, v5);
1270 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1271 +    }
1272 +    else if (he->he_sig == AP_HOOK_SIG7(int, ptr, ptr, ptr, ptr, int, ptr)) {
1273 +        /* Call: int func(ptr,ptr,ptr,ptr,int,ptr) */
1274 +        void *v1 = va_arg(ap, va_type(ptr));
1275 +        void *v2 = va_arg(ap, va_type(ptr));
1276 +        void *v3 = va_arg(ap, va_type(ptr));
1277 +        void *v4 = va_arg(ap, va_type(ptr));
1278 +        int   v5 = va_arg(ap, va_type(int));
1279 +        void *v6 = va_arg(ap, va_type(ptr));
1280 +        *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5, v6);
1281 +        rc = (*((int *)v_rc) != he->he_modeval.v_int);
1282 +    }
1283 +    else if (he->he_sig == AP_HOOK_SIG6(ptr, ptr, ptr, ptr, ptr, ptr)) {
1284 +        /* Call: ptr func(ptr,ptr,ptr,ptr,ptr) */
1285 +        void *v1 = va_arg(ap, va_type(ptr));
1286 +        void *v2 = va_arg(ap, va_type(ptr));
1287 +        void *v3 = va_arg(ap, va_type(ptr));
1288 +        void *v4 = va_arg(ap, va_type(ptr));
1289 +        void *v5 = va_arg(ap, va_type(ptr));
1290 +        *((void * *)v_rc) = ((void *(*)(void *, void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
1291 +        rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
1292 +    }
1293 +    else if (he->he_sig == AP_HOOK_SIG2(void, ptr)) {
1294 +        /* Call: void func(ptr) */
1295 +        void *v1 = va_arg(ap, va_type(ptr));
1296 +        ((void(*)(void *))(hf->hf_ptr))(v1);
1297 +    }
1298 +    else if (he->he_sig == AP_HOOK_SIG4(void, ptr, int, int)) {
1299 +        /* Call: void func(ptr,int,int) */
1300 +        void *v1 = va_arg(ap, va_type(ptr));
1301 +        int   v2 = va_arg(ap, va_type(int));
1302 +        int   v3 = va_arg(ap, va_type(int));
1303 +        ((void(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
1304 +    }
1305 +    else if (he->he_sig == AP_HOOK_SIG3(void, ptr, ptr)) {
1306 +        /* Call: void func(ptr,ptr) */
1307 +        void *v1 = va_arg(ap, va_type(ptr));
1308 +        void *v2 = va_arg(ap, va_type(ptr));
1309 +        ((void(*)(void *, void *))(hf->hf_ptr))(v1, v2);
1310 +    }
1311 +    else if (he->he_sig == AP_HOOK_SIG4(void, ptr, ptr, ptr)) {
1312 +        /* Call: void func(ptr,ptr,ptr) */
1313 +        void *v1 = va_arg(ap, va_type(ptr));
1314 +        void *v2 = va_arg(ap, va_type(ptr));
1315 +        void *v3 = va_arg(ap, va_type(ptr));
1316 +        ((void(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
1317 +    }
1318 +    else if (he->he_sig == AP_HOOK_SIG5(void, ptr, ptr, ptr, ptr)) {
1319 +        /* Call: void func(ptr,ptr,ptr,ptr) */
1320 +        void *v1 = va_arg(ap, va_type(ptr));
1321 +        void *v2 = va_arg(ap, va_type(ptr));
1322 +        void *v3 = va_arg(ap, va_type(ptr));
1323 +        void *v4 = va_arg(ap, va_type(ptr));
1324 +        ((void(*)(void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4);
1325 +    }
1326 +    /* ----END GENERATED SECTION---------- */
1327 +    else
1328 +        ap_log_assert("hook signature not implemented", __FILE__, __LINE__);
1329 +
1330 +    if (he->he_modeid == AP_HOOK_MODE_ALL)
1331 +        rc = FALSE;
1332 +    else if (he->he_modeid == AP_HOOK_MODE_TOPMOST)
1333 +        rc = TRUE;
1334 +
1335 +    return rc;
1336 +}
1337 +
1338 +#endif /* EAPI */
1339 +
1340 +/*
1341 +=cut
1342 +##
1343 +##  Embedded Perl script for generating the dispatch section
1344 +##
1345 +
1346 +require 5.003;
1347 +use strict;
1348 +
1349 +#   configuration
1350 +my $file  = $0;
1351 +my $begin = '----BEGIN GENERATED SECTION--------';
1352 +my $end   = '----END GENERATED SECTION----------';
1353 +
1354 +#   special command: find used signatures
1355 +if ($ARGV[0] eq 'used') {
1356 +    my @S = `find .. -type f -name "*.c" -print`;
1357 +    my $s;
1358 +    my %T = ();
1359 +    foreach $s (@S) {
1360 +        $s =~ s|\n$||;
1361 +        open(FP, "<$s") || die;
1362 +        my $source = '';
1363 +        $source .= $_ while (<FP>);
1364 +        close(FP);
1365 +        my %seen = ();
1366 +        sub printme {
1367 +            my ($src, $hook, $sig) = @_;
1368 +            return if ($seen{$hook} == 1);
1369 +            $seen{$hook} = 1;
1370 +            my ($rc, $args) = ($sig =~ m|^([^,]+)(.*)$|);
1371 +            $args =~ s|^,||;
1372 +            $src =~ s|^.+/||;
1373 +            my $sig = sprintf("%-6sfunc(%s)", $rc, $args);
1374 +            $T{$sig}++; 
1375 +        }
1376 +        $source =~ s|\("([^"]+)",\s*AP_HOOK_SIG[0-9]\((.+?)\)|&printme($s, $1, $2), ''|sge;
1377 +    }
1378 +    my $t;
1379 +    foreach $t (sort(keys(%T))) {
1380 +        printf("     *    %-40s [%dx]\n", $t, $T{$t});
1381 +    }
1382 +    exit(0);
1383 +}
1384 +
1385 +#   read ourself and keep a backup
1386 +open(FP, "<$file") || die;
1387 +my $source = '';
1388 +$source .= $_ while (<FP>);
1389 +close(FP);
1390 +open(FP, ">$file.bak") || die;
1391 +print FP $source;
1392 +close(FP);
1393 +
1394 +#   now parse the signature lines and update the code
1395 +my $o = '';
1396 +my $next = 0;
1397 +my $line;
1398 +my %seen = ();
1399 +foreach $line (split(/\n/, $source)) {
1400 +    next if (not $line =~ m|\*\s+\S+\s+func\(.*\)|);
1401 +    my ($sig, $rc, $param) = ($line =~ m|\*\s+((\S+)\s+func\((.*?)\))|);
1402 +    $sig =~ s|\s+| |g;
1403 +
1404 +    next if ($seen{$sig} == 1);
1405 +    $seen{$sig} = 1;
1406 +
1407 +    print "Generating code for `$sig'\n";
1408 +
1409 +    my @S = ($rc, split(/[\s,]+/, $param));
1410 +    my @RS = @S;
1411 +    my $i;
1412 +    for ($i = 0; $i <= $#RS; $i++) {
1413 +        $RS[$i] = 'void *' if ($RS[$i] eq 'ptr');
1414 +        $RS[$i] = 'void *' if ($RS[$i] eq 'ctx');
1415 +    }
1416 +
1417 +    $o .= "else " if ($next); $next++;
1418 +    $o .= sprintf("if (he->he_sig == AP_HOOK_SIG%d(%s)) {\n", $#S+1, join(', ',@S));
1419 +    $o .= sprintf("    \/\* Call: %s \*\/\n", $sig);
1420 +    for ($i = 1; $i <= $#S; $i++) {
1421 +        $o .= sprintf("    %-6sv%d = va_arg(ap, va_type(%s));\n", $RS[$i], $i, $S[$i]);
1422 +    }
1423 +    $o .= "    ";
1424 +    $o .= sprintf("*((%s *)v_rc) = ", $RS[0]) if ($S[0] ne 'void');
1425 +    $o .= sprintf("((%s(*)(%s))(hf->hf_ptr))", $RS[0], join(', ', @RS[1..$#RS]));
1426 +    $o .= "(";
1427 +    for ($i = 1; $i <= $#S; $i++) {
1428 +        $o .= "hf->hf_ctx" if ($S[$i] eq 'ctx');
1429 +        $o .= sprintf("v%d", $i) if ($S[$i] ne 'ctx');
1430 +        $o .= ", " if ($i < $#S);
1431 +    }
1432 +    $o .= ");\n";
1433 +    $o .= sprintf("    rc = (*((%s *)v_rc) != he->he_modeval.v_%s);\n", 
1434 +                  $RS[0], $S[0]) if ($S[0] ne 'void');
1435 +    $o .= "}\n";
1436 +}
1437 +
1438 +#   insert the generated code at the target location
1439 +$o =~ s|^|    |mg;
1440 +$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s;
1441 +
1442 +#   and update the source on disk
1443 +print "Updating file `$file'\n";
1444 +open(FP, ">$file") || die;
1445 +print FP $source;
1446 +close(FP);
1447 +
1448 +=pod
1449 +*/
1450 diff -urN apache_1.3.14.orig/src/ap/ap_mm.c apache_1.3.14/src/ap/ap_mm.c
1451 --- apache_1.3.14.orig/src/ap/ap_mm.c   Thu Jan  1 01:00:00 1970
1452 +++ apache_1.3.14/src/ap/ap_mm.c        Sat Nov 11 20:49:14 2000
1453 @@ -0,0 +1,178 @@
1454 +/* ====================================================================
1455 + * Copyright (c) 1999-2000 The Apache Group.  All rights reserved.
1456 + *
1457 + * Redistribution and use in source and binary forms, with or without
1458 + * modification, are permitted provided that the following conditions
1459 + * are met:
1460 + *
1461 + * 1. Redistributions of source code must retain the above copyright
1462 + *    notice, this list of conditions and the following disclaimer. 
1463 + *
1464 + * 2. Redistributions in binary form must reproduce the above copyright
1465 + *    notice, this list of conditions and the following disclaimer in
1466 + *    the documentation and/or other materials provided with the
1467 + *    distribution.
1468 + *
1469 + * 3. All advertising materials mentioning features or use of this
1470 + *    software must display the following acknowledgment:
1471 + *    "This product includes software developed by the Apache Group
1472 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
1473 + *
1474 + * 4. The names "Apache Server" and "Apache Group" must not be used to
1475 + *    endorse or promote products derived from this software without
1476 + *    prior written permission. For written permission, please contact
1477 + *    apache@apache.org.
1478 + *
1479 + * 5. Products derived from this software may not be called "Apache"
1480 + *    nor may "Apache" appear in their names without prior written
1481 + *    permission of the Apache Group.
1482 + *
1483 + * 6. Redistributions of any form whatsoever must retain the following
1484 + *    acknowledgment:
1485 + *    "This product includes software developed by the Apache Group
1486 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
1487 + *
1488 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
1489 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1490 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1491 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
1492 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1493 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1494 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1495 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1496 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1497 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1498 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1499 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1500 + * ====================================================================
1501 + *
1502 + * This software consists of voluntary contributions made by many
1503 + * individuals on behalf of the Apache Group and was originally based
1504 + * on public domain software written at the National Center for
1505 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
1506 + * For more information on the Apache Group and the Apache HTTP server
1507 + * project, please see <http://www.apache.org/>.
1508 + */
1509 +
1510 +/*
1511 +**  ap_mm.c -- wrapper for MM shared memory library
1512 +**
1513 +**  This file has two reason:
1514 +**
1515 +**  1. Under DSO context we need stubs inside the Apache core code
1516 +**     to make sure the MM library's code is actually available
1517 +**     to the module DSOs.
1518 +**
1519 +**  2. When the MM library cannot be built on the current platform
1520 +**     still provide dummy stubs so modules using the ap_mm_xxx()
1521 +**     functions can be still built. But modules should use
1522 +**     ap_mm_useable() to find out whether they really can use
1523 +**     the MM stuff.
1524 +*/
1525 +                                       /*
1526 +                                        * "What you see is all you get."
1527 +                                        *     -- Brian Kernighan
1528 +                                        */
1529 +#ifdef EAPI
1530 +
1531 +#include "httpd.h"
1532 +#include "ap_mm.h"
1533 +
1534 +#ifdef EAPI_MM
1535 +#include "mm.h"
1536 +API_EXPORT(int) ap_mm_useable(void) { return TRUE;  }
1537 +#define STUB(val,nul)               { return val;   }
1538 +#define STUB_STMT(stmt)             { stmt; return; }
1539 +#else
1540 +API_EXPORT(int) ap_mm_useable(void) { return FALSE; }
1541 +#define STUB(val,nul)               { return nul;   }
1542 +#define STUB_STMT(stmt)             { return;       }
1543 +#endif
1544 +
1545 +API_EXPORT(int) ap_MM_create(size_t size, char *file) 
1546 +    STUB(MM_create(size, file), FALSE)
1547 +API_EXPORT(int) ap_MM_permission(mode_t mode, uid_t owner, gid_t group) 
1548 +    STUB(MM_permission(mode, owner, group), -1)
1549 +API_EXPORT(void) ap_MM_destroy(void)
1550 +    STUB_STMT(MM_destroy())
1551 +API_EXPORT(int) ap_MM_lock(ap_mm_lock_mode mode)
1552 +    STUB(MM_lock(mode), FALSE)
1553 +API_EXPORT(int) ap_MM_unlock(void)
1554 +    STUB(MM_unlock(), FALSE)
1555 +API_EXPORT(void *) ap_MM_malloc(size_t size)
1556 +    STUB(MM_malloc(size), NULL)
1557 +API_EXPORT(void *) ap_MM_realloc(void *ptr, size_t size)
1558 +    STUB(MM_realloc(ptr, size), NULL)
1559 +API_EXPORT(void) ap_MM_free(void *ptr)
1560 +    STUB_STMT(MM_free(ptr))
1561 +API_EXPORT(void *) ap_MM_calloc(size_t number, size_t size)
1562 +    STUB(MM_calloc(number, size), NULL)
1563 +API_EXPORT(char *) ap_MM_strdup(const char *str)
1564 +    STUB(MM_strdup(str), NULL)
1565 +API_EXPORT(size_t) ap_MM_sizeof(void *ptr)
1566 +    STUB(MM_sizeof(ptr), 0)
1567 +API_EXPORT(size_t) ap_MM_maxsize(void)
1568 +    STUB(MM_maxsize(), 0)
1569 +API_EXPORT(size_t) ap_MM_available(void)
1570 +    STUB(MM_available(), 0)
1571 +API_EXPORT(char *) ap_MM_error(void)
1572 +    STUB(MM_error(), NULL)
1573 +
1574 +API_EXPORT(AP_MM *) ap_mm_create(size_t size, char *file)
1575 +    STUB(mm_create(size, file), NULL)
1576 +API_EXPORT(int) ap_mm_permission(AP_MM *mm, mode_t mode, uid_t owner, gid_t group) 
1577 +    STUB(mm_permission(mm, mode, owner, group), -1)
1578 +API_EXPORT(void) ap_mm_destroy(AP_MM *mm)
1579 +    STUB_STMT(mm_destroy(mm))
1580 +API_EXPORT(int) ap_mm_lock(AP_MM *mm, ap_mm_lock_mode mode)
1581 +    STUB(mm_lock(mm, mode), FALSE)
1582 +API_EXPORT(int) ap_mm_unlock(AP_MM *mm)
1583 +    STUB(mm_unlock(mm), FALSE)
1584 +API_EXPORT(void *) ap_mm_malloc(AP_MM *mm, size_t size)
1585 +    STUB(mm_malloc(mm, size), NULL)
1586 +API_EXPORT(void *) ap_mm_realloc(AP_MM *mm, void *ptr, size_t size)
1587 +    STUB(mm_realloc(mm, ptr, size), NULL)
1588 +API_EXPORT(void) ap_mm_free(AP_MM *mm, void *ptr)
1589 +    STUB_STMT(mm_free(mm, ptr))
1590 +API_EXPORT(void *) ap_mm_calloc(AP_MM *mm, size_t number, size_t size)
1591 +    STUB(mm_calloc(mm, number, size), NULL)
1592 +API_EXPORT(char *) ap_mm_strdup(AP_MM *mm, const char *str)
1593 +    STUB(mm_strdup(mm, str), NULL)
1594 +API_EXPORT(size_t) ap_mm_sizeof(AP_MM *mm, void *ptr)
1595 +    STUB(mm_sizeof(mm, ptr), 0)
1596 +API_EXPORT(size_t) ap_mm_maxsize(void)
1597 +    STUB(mm_maxsize(), 0)
1598 +API_EXPORT(size_t) ap_mm_available(AP_MM *mm)
1599 +    STUB(mm_available(mm), 0)
1600 +API_EXPORT(char *) ap_mm_error(void)
1601 +    STUB(mm_error(), NULL)
1602 +API_EXPORT(void) ap_mm_display_info(AP_MM *mm)
1603 +    STUB_STMT(mm_display_info(mm))
1604 +
1605 +API_EXPORT(void *) ap_mm_core_create(size_t size, char *file)
1606 +    STUB(mm_core_create(size, file), NULL)
1607 +API_EXPORT(int) ap_mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group) 
1608 +    STUB(mm_core_permission(core, mode, owner, group), -1)
1609 +API_EXPORT(void) ap_mm_core_delete(void *core)
1610 +    STUB_STMT(mm_core_delete(core))
1611 +API_EXPORT(size_t) ap_mm_core_size(void *core)
1612 +    STUB(mm_core_size(core), 0)
1613 +API_EXPORT(int) ap_mm_core_lock(void *core, ap_mm_lock_mode mode)
1614 +    STUB(mm_core_lock(core, mode), FALSE)
1615 +API_EXPORT(int) ap_mm_core_unlock(void *core)
1616 +    STUB(mm_core_unlock(core), FALSE)
1617 +API_EXPORT(size_t) ap_mm_core_maxsegsize(void)
1618 +    STUB(mm_core_maxsegsize(), 0)
1619 +API_EXPORT(size_t) ap_mm_core_align2page(size_t size)
1620 +    STUB(mm_core_align2page(size), 0)
1621 +API_EXPORT(size_t) ap_mm_core_align2word(size_t size)
1622 +    STUB(mm_core_align2word(size), 0)
1623 +
1624 +API_EXPORT(void) ap_mm_lib_error_set(unsigned int type, const char *str)
1625 +    STUB_STMT(mm_lib_error_set(type, str))
1626 +API_EXPORT(char *) ap_mm_lib_error_get(void)
1627 +    STUB(mm_lib_error_get(), NULL)
1628 +API_EXPORT(int) ap_mm_lib_version(void)
1629 +    STUB(mm_lib_version(), 0)
1630 +
1631 +#endif /* EAPI */
1632 diff -urN apache_1.3.14.orig/src/include/ap_alloc.h apache_1.3.14/src/include/ap_alloc.h
1633 --- apache_1.3.14.orig/src/include/ap_alloc.h   Fri Jun  2 01:42:23 2000
1634 +++ apache_1.3.14/src/include/ap_alloc.h        Sat Nov 11 20:49:14 2000
1635 @@ -94,6 +94,15 @@
1636  pool * ap_init_alloc(void);            /* Set up everything */
1637  void ap_cleanup_alloc(void);
1638  API_EXPORT(pool *) ap_make_sub_pool(pool *);   /* All pools are subpools of permanent_pool */
1639 +#if defined(EAPI)
1640 +typedef enum { AP_POOL_RD, AP_POOL_RW } ap_pool_lock_mode;
1641 +int ap_shared_pool_possible(void);
1642 +void ap_init_alloc_shared(int);
1643 +void ap_kill_alloc_shared(void);
1644 +API_EXPORT(pool *) ap_make_shared_sub_pool(pool *);
1645 +API_EXPORT(int) ap_acquire_pool(pool *, ap_pool_lock_mode);
1646 +API_EXPORT(int) ap_release_pool(pool *);
1647 +#endif
1648  API_EXPORT(void) ap_destroy_pool(pool *);
1649  
1650  /* pools have nested lifetimes -- sub_pools are destroyed when the
1651 diff -urN apache_1.3.14.orig/src/include/ap_ctx.h apache_1.3.14/src/include/ap_ctx.h
1652 --- apache_1.3.14.orig/src/include/ap_ctx.h     Thu Jan  1 01:00:00 1970
1653 +++ apache_1.3.14/src/include/ap_ctx.h  Sat Nov 11 20:49:14 2000
1654 @@ -0,0 +1,110 @@
1655 +/* ====================================================================
1656 + * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
1657 + *
1658 + * Redistribution and use in source and binary forms, with or without
1659 + * modification, are permitted provided that the following conditions
1660 + * are met:
1661 + *
1662 + * 1. Redistributions of source code must retain the above copyright
1663 + *    notice, this list of conditions and the following disclaimer. 
1664 + *
1665 + * 2. Redistributions in binary form must reproduce the above copyright
1666 + *    notice, this list of conditions and the following disclaimer in
1667 + *    the documentation and/or other materials provided with the
1668 + *    distribution.
1669 + *
1670 + * 3. All advertising materials mentioning features or use of this
1671 + *    software must display the following acknowledgment:
1672 + *    "This product includes software developed by the Apache Group
1673 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
1674 + *
1675 + * 4. The names "Apache Server" and "Apache Group" must not be used to
1676 + *    endorse or promote products derived from this software without
1677 + *    prior written permission. For written permission, please contact
1678 + *    apache@apache.org.
1679 + *
1680 + * 5. Products derived from this software may not be called "Apache"
1681 + *    nor may "Apache" appear in their names without prior written
1682 + *    permission of the Apache Group.
1683 + *
1684 + * 6. Redistributions of any form whatsoever must retain the following
1685 + *    acknowledgment:
1686 + *    "This product includes software developed by the Apache Group
1687 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
1688 + *
1689 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
1690 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1691 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1692 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
1693 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1694 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1695 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1696 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1697 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1698 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1699 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1700 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1701 + * ====================================================================
1702 + *
1703 + * This software consists of voluntary contributions made by many
1704 + * individuals on behalf of the Apache Group and was originally based
1705 + * on public domain software written at the National Center for
1706 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
1707 + * For more information on the Apache Group and the Apache HTTP server
1708 + * project, please see <http://www.apache.org/>.
1709 + *
1710 + */
1711 +
1712 +/*
1713 +**  Generic Context Interface for Apache
1714 +**  Written by Ralf S. Engelschall <rse@engelschall.com> 
1715 +*/
1716 +
1717 +#ifdef EAPI
1718 +
1719 +#ifndef AP_CTX_H
1720 +#define AP_CTX_H
1721 +
1722 +#ifndef FALSE
1723 +#define FALSE 0
1724 +#define TRUE  !FALSE
1725 +#endif
1726 +
1727 +/*
1728 + * Internal Context Record Definition
1729 + */
1730 +
1731 +#define AP_CTX_MAX_ENTRIES 1024
1732 +
1733 +typedef struct {
1734 +    char *ce_key;
1735 +    void *ce_val;
1736 +} ap_ctx_entry;
1737 +
1738 +typedef struct {
1739 +    pool          *cr_pool;
1740 +    ap_ctx_entry **cr_entry;
1741 +} ap_ctx_rec;
1742 +
1743 +typedef ap_ctx_rec ap_ctx;
1744 +
1745 +/*
1746 + * Some convinience macros for storing _numbers_ 0...n in contexts, i.e.
1747 + * treating numbers as pointers but keeping track of the NULL return code of
1748 + * ap_ctx_get.
1749 + */
1750 +#define AP_CTX_NUM2PTR(n) (void *)((unsigned int)(n)+1)
1751 +#define AP_CTX_PTR2NUM(p) (unsigned int)(((char *)(p))-1)
1752 +
1753 +/*
1754 + * Prototypes for Context Handling Functions
1755 + */
1756 +
1757 +API_EXPORT(ap_ctx *)ap_ctx_new(pool *p);
1758 +API_EXPORT(void)    ap_ctx_set(ap_ctx *ctx, char *key, void *val);
1759 +API_EXPORT(void *)  ap_ctx_get(ap_ctx *ctx, char *key);
1760 +API_EXPORT(ap_ctx *)ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base);
1761 +
1762 +#endif /* AP_CTX_H */
1763 +
1764 +#endif /* EAPI */
1765 diff -urN apache_1.3.14.orig/src/include/ap_hook.h apache_1.3.14/src/include/ap_hook.h
1766 --- apache_1.3.14.orig/src/include/ap_hook.h    Thu Jan  1 01:00:00 1970
1767 +++ apache_1.3.14/src/include/ap_hook.h Sat Nov 11 20:49:14 2000
1768 @@ -0,0 +1,710 @@
1769 +#if 0
1770 +=cut
1771 +#endif
1772 +/* ====================================================================
1773 + * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
1774 + *
1775 + * Redistribution and use in source and binary forms, with or without
1776 + * modification, are permitted provided that the following conditions
1777 + * are met:
1778 + *
1779 + * 1. Redistributions of source code must retain the above copyright
1780 + *    notice, this list of conditions and the following disclaimer. 
1781 + *
1782 + * 2. Redistributions in binary form must reproduce the above copyright
1783 + *    notice, this list of conditions and the following disclaimer in
1784 + *    the documentation and/or other materials provided with the
1785 + *    distribution.
1786 + *
1787 + * 3. All advertising materials mentioning features or use of this
1788 + *    software must display the following acknowledgment:
1789 + *    "This product includes software developed by the Apache Group
1790 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
1791 + *
1792 + * 4. The names "Apache Server" and "Apache Group" must not be used to
1793 + *    endorse or promote products derived from this software without
1794 + *    prior written permission. For written permission, please contact
1795 + *    apache@apache.org.
1796 + *
1797 + * 5. Products derived from this software may not be called "Apache"
1798 + *    nor may "Apache" appear in their names without prior written
1799 + *    permission of the Apache Group.
1800 + *
1801 + * 6. Redistributions of any form whatsoever must retain the following
1802 + *    acknowledgment:
1803 + *    "This product includes software developed by the Apache Group
1804 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
1805 + *
1806 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
1807 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1808 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1809 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
1810 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1811 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1812 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1813 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1814 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1815 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1816 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1817 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1818 + * ====================================================================
1819 + *
1820 + * This software consists of voluntary contributions made by many
1821 + * individuals on behalf of the Apache Group and was originally based
1822 + * on public domain software written at the National Center for
1823 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
1824 + * For more information on the Apache Group and the Apache HTTP server
1825 + * project, please see <http://www.apache.org/>.
1826 + *
1827 + */
1828 +
1829 +/*
1830 +**  Implementation of a Generic Hook Interface for Apache
1831 +**  Written by Ralf S. Engelschall <rse@engelschall.com> 
1832 +**
1833 +**  See POD document at end of this file for description.
1834 +**  View it with the command ``pod2man ap_hook.h | nroff -man | more''
1835 +**
1836 +**  Attention: This header file is a little bit tricky.
1837 +**             It's a combination of a C source and an embedded POD document
1838 +**             The purpose of this is to have both things together at one
1839 +**             place. So you can both pass this file to the C compiler and 
1840 +**             the pod2man translater.
1841 +*/
1842 +
1843 +#ifdef EAPI
1844 +
1845 +#ifndef AP_HOOK_H
1846 +#define AP_HOOK_H
1847 +
1848 +/*
1849 + * Function Signature Specification:
1850 + *
1851 + * We encode the complete signature ingredients as a bitfield
1852 + * stored in a single unsigned long integer value, which can be
1853 + * constructed with AP_HOOK_SIGx(...)
1854 + */
1855 +
1856 +/* the type of the signature bitfield */
1857 +typedef unsigned long int ap_hook_sig;
1858 +
1859 +/* the mask (bin) 111 (hex 0x7) for the triples in the bitfield */
1860 +#define AP_HOOK_SIG_TRIPLE_MASK  0x7
1861 +
1862 +/* the position of the triple */
1863 +#define AP_HOOK_SIG_TRIPLE_POS(n) ((n)*3)
1864 +
1865 +/* the constructor for triple #n with value v */
1866 +#define AP_HOOK_SIG_TRIPLE(n,v) \
1867 +        (((ap_hook_sig)(v))<<((AP_HOOK_##n)*3))
1868 +
1869 +/* the check whether triple #n in sig contains value v */
1870 +#define AP_HOOK_SIG_HAS(sig,n,v) \
1871 +        ((((ap_hook_sig)(sig))&AP_HOOK_SIG_TRIPLE(n, AP_HOOK_SIG_TRIPLE_MASK)) == (AP_HOOK_##n##_##v))
1872 +
1873 +/* utility function to get triple #n in sig */
1874 +#define AP_HOOK_SIG_TRIPLE_GET(sig,n) \
1875 +        ((((ap_hook_sig)(sig))>>AP_HOOK_SIG_TRIPLE_POS(n))&(AP_HOOK_SIG_TRIPLE_MASK))
1876 +
1877 +/* utility function to set triple #n in sig to value v */
1878 +#define AP_HOOK_SIG_TRIPLE_SET(sig,n,v) \
1879 +        ((((ap_hook_sig)(sig))&~(AP_HOOK_SIG_TRIPLE_MASK<<AP_HOOK_SIG_TRIPLE_POS(n)))|((v)<<AP_HOOK_SIG_TRIPLE_POS(n)))
1880 +
1881 +/* define the ingredients for the triple #0: id stuff */
1882 +#define AP_HOOK_ID          0
1883 +#define AP_HOOK_ID_ok       AP_HOOK_SIG_TRIPLE(ID,0)
1884 +#define AP_HOOK_ID_undef    AP_HOOK_SIG_TRIPLE(ID,1)
1885 +
1886 +/* define the ingredients for the triple #1: return code */
1887 +#define AP_HOOK_RC          1
1888 +#define AP_HOOK_RC_void     AP_HOOK_SIG_TRIPLE(RC,0)
1889 +#define AP_HOOK_RC_char     AP_HOOK_SIG_TRIPLE(RC,1)
1890 +#define AP_HOOK_RC_int      AP_HOOK_SIG_TRIPLE(RC,2)
1891 +#define AP_HOOK_RC_long     AP_HOOK_SIG_TRIPLE(RC,3)
1892 +#define AP_HOOK_RC_float    AP_HOOK_SIG_TRIPLE(RC,4)
1893 +#define AP_HOOK_RC_double   AP_HOOK_SIG_TRIPLE(RC,5)
1894 +#define AP_HOOK_RC_ptr      AP_HOOK_SIG_TRIPLE(RC,6)
1895 +
1896 +/* define the ingredients for the triple #2: argument 1 */
1897 +#define AP_HOOK_A1          2
1898 +#define AP_HOOK_A1_ctx      AP_HOOK_SIG_TRIPLE(A1,0)
1899 +#define AP_HOOK_A1_char     AP_HOOK_SIG_TRIPLE(A1,1)
1900 +#define AP_HOOK_A1_int      AP_HOOK_SIG_TRIPLE(A1,2)
1901 +#define AP_HOOK_A1_long     AP_HOOK_SIG_TRIPLE(A1,3)
1902 +#define AP_HOOK_A1_float    AP_HOOK_SIG_TRIPLE(A1,4)
1903 +#define AP_HOOK_A1_double   AP_HOOK_SIG_TRIPLE(A1,5)
1904 +#define AP_HOOK_A1_ptr      AP_HOOK_SIG_TRIPLE(A1,6)
1905 +
1906 +/* define the ingredients for the triple #3: argument 2 */
1907 +#define AP_HOOK_A2          3
1908 +#define AP_HOOK_A2_ctx      AP_HOOK_SIG_TRIPLE(A2,0)
1909 +#define AP_HOOK_A2_char     AP_HOOK_SIG_TRIPLE(A2,1)
1910 +#define AP_HOOK_A2_int      AP_HOOK_SIG_TRIPLE(A2,2)
1911 +#define AP_HOOK_A2_long     AP_HOOK_SIG_TRIPLE(A2,3)
1912 +#define AP_HOOK_A2_float    AP_HOOK_SIG_TRIPLE(A2,4)
1913 +#define AP_HOOK_A2_double   AP_HOOK_SIG_TRIPLE(A2,5)
1914 +#define AP_HOOK_A2_ptr      AP_HOOK_SIG_TRIPLE(A2,6)
1915 +
1916 +/* define the ingredients for the triple #4: argument 3 */
1917 +#define AP_HOOK_A3          4
1918 +#define AP_HOOK_A3_ctx      AP_HOOK_SIG_TRIPLE(A3,0)
1919 +#define AP_HOOK_A3_char     AP_HOOK_SIG_TRIPLE(A3,1)
1920 +#define AP_HOOK_A3_int      AP_HOOK_SIG_TRIPLE(A3,2)
1921 +#define AP_HOOK_A3_long     AP_HOOK_SIG_TRIPLE(A3,3)
1922 +#define AP_HOOK_A3_float    AP_HOOK_SIG_TRIPLE(A3,4)
1923 +#define AP_HOOK_A3_double   AP_HOOK_SIG_TRIPLE(A3,5)
1924 +#define AP_HOOK_A3_ptr      AP_HOOK_SIG_TRIPLE(A3,6)
1925 +
1926 +/* define the ingredients for the triple #5: argument 4 */
1927 +#define AP_HOOK_A4          5
1928 +#define AP_HOOK_A4_ctx      AP_HOOK_SIG_TRIPLE(A4,0)
1929 +#define AP_HOOK_A4_char     AP_HOOK_SIG_TRIPLE(A4,1)
1930 +#define AP_HOOK_A4_int      AP_HOOK_SIG_TRIPLE(A4,2)
1931 +#define AP_HOOK_A4_long     AP_HOOK_SIG_TRIPLE(A4,3)
1932 +#define AP_HOOK_A4_float    AP_HOOK_SIG_TRIPLE(A4,4)
1933 +#define AP_HOOK_A4_double   AP_HOOK_SIG_TRIPLE(A4,5)
1934 +#define AP_HOOK_A4_ptr      AP_HOOK_SIG_TRIPLE(A4,6)
1935 +
1936 +/* define the ingredients for the triple #6: argument 5 */
1937 +#define AP_HOOK_A5          6
1938 +#define AP_HOOK_A5_ctx      AP_HOOK_SIG_TRIPLE(A5,0)
1939 +#define AP_HOOK_A5_char     AP_HOOK_SIG_TRIPLE(A5,1)
1940 +#define AP_HOOK_A5_int      AP_HOOK_SIG_TRIPLE(A5,2)
1941 +#define AP_HOOK_A5_long     AP_HOOK_SIG_TRIPLE(A5,3)
1942 +#define AP_HOOK_A5_float    AP_HOOK_SIG_TRIPLE(A5,4)
1943 +#define AP_HOOK_A5_double   AP_HOOK_SIG_TRIPLE(A5,5)
1944 +#define AP_HOOK_A5_ptr      AP_HOOK_SIG_TRIPLE(A5,6)
1945 +
1946 +/* define the ingredients for the triple #7: argument 6 */
1947 +#define AP_HOOK_A6          7
1948 +#define AP_HOOK_A6_ctx      AP_HOOK_SIG_TRIPLE(A6,0)
1949 +#define AP_HOOK_A6_char     AP_HOOK_SIG_TRIPLE(A6,1)
1950 +#define AP_HOOK_A6_int      AP_HOOK_SIG_TRIPLE(A6,2)
1951 +#define AP_HOOK_A6_long     AP_HOOK_SIG_TRIPLE(A6,3)
1952 +#define AP_HOOK_A6_float    AP_HOOK_SIG_TRIPLE(A6,4)
1953 +#define AP_HOOK_A6_double   AP_HOOK_SIG_TRIPLE(A6,5)
1954 +#define AP_HOOK_A6_ptr      AP_HOOK_SIG_TRIPLE(A6,6)
1955 +
1956 +/* define the ingredients for the triple #8: argument 7 */
1957 +#define AP_HOOK_A7          8
1958 +#define AP_HOOK_A7_ctx      AP_HOOK_SIG_TRIPLE(A7,0)
1959 +#define AP_HOOK_A7_char     AP_HOOK_SIG_TRIPLE(A7,1)
1960 +#define AP_HOOK_A7_int      AP_HOOK_SIG_TRIPLE(A7,2)
1961 +#define AP_HOOK_A7_long     AP_HOOK_SIG_TRIPLE(A7,3)
1962 +#define AP_HOOK_A7_float    AP_HOOK_SIG_TRIPLE(A7,4)
1963 +#define AP_HOOK_A7_double   AP_HOOK_SIG_TRIPLE(A7,5)
1964 +#define AP_HOOK_A7_ptr      AP_HOOK_SIG_TRIPLE(A7,6)
1965 +
1966 +/* define the ingredients for the triple #9: argument 8 */
1967 +#define AP_HOOK_A8          9
1968 +#define AP_HOOK_A8_ctx      AP_HOOK_SIG_TRIPLE(9,0)
1969 +#define AP_HOOK_A8_char     AP_HOOK_SIG_TRIPLE(9,1)
1970 +#define AP_HOOK_A8_int      AP_HOOK_SIG_TRIPLE(9,2)
1971 +#define AP_HOOK_A8_long     AP_HOOK_SIG_TRIPLE(9,3)
1972 +#define AP_HOOK_A8_float    AP_HOOK_SIG_TRIPLE(9,4)
1973 +#define AP_HOOK_A8_double   AP_HOOK_SIG_TRIPLE(9,5)
1974 +#define AP_HOOK_A8_ptr      AP_HOOK_SIG_TRIPLE(9,6)
1975 +  
1976 +/* the constructor for unknown signatures */
1977 +#define AP_HOOK_SIG_UNKNOWN AP_HOOK_ID_undef
1978 +
1979 +/* the constructor for signatures with 1 type */
1980 +#define AP_HOOK_SIG1(rc) \
1981 +        (AP_HOOK_RC_##rc)
1982 +
1983 +/* the constructor for signatures with 2 types */
1984 +#define AP_HOOK_SIG2(rc,a1) \
1985 +        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1)
1986 +
1987 +/* the constructor for signatures with 3 types */
1988 +#define AP_HOOK_SIG3(rc,a1,a2) \
1989 +        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2)
1990 +
1991 +/* the constructor for signatures with 4 types */
1992 +#define AP_HOOK_SIG4(rc,a1,a2,a3) \
1993 +        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3)
1994 +
1995 +/* the constructor for signatures with 5 types */
1996 +#define AP_HOOK_SIG5(rc,a1,a2,a3,a4) \
1997 +        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4)
1998 +
1999 +/* the constructor for signatures with 6 types */
2000 +#define AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5) \
2001 +        (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5)
2002 +
2003 +/* the constructor for signatures with 7 types */
2004 +#define AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6) \
2005 +        (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)
2006 +
2007 +/* the constructor for signatures with 8 types */
2008 +#define AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7) \
2009 +        (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)
2010 +
2011 +/* the constructor for signatures with 9 types */
2012 +#define AP_HOOK_SIG9(rc,a1,a2,a3,a4,a5,a6,a7,a8) \
2013 +        (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)
2014 +
2015 +/*
2016 + * Return Value Mode Identification
2017 + */
2018 +
2019 +/* the type of the return value modes */
2020 +typedef unsigned int ap_hook_mode;
2021 +
2022 +/* the mode of the return value */
2023 +#define AP_HOOK_MODE_UNKNOWN  0
2024 +#define AP_HOOK_MODE_TOPMOST  1
2025 +#define AP_HOOK_MODE_DECLINE  2
2026 +#define AP_HOOK_MODE_DECLTMP  3
2027 +#define AP_HOOK_MODE_ALL      4
2028 +
2029 +/* the constructors for the return value modes */
2030 +#define AP_HOOK_TOPMOST       AP_HOOK_MODE_TOPMOST
2031 +#define AP_HOOK_DECLINE(val)  AP_HOOK_MODE_DECLINE, (val)   
2032 +#define AP_HOOK_DECLTMP(val)  AP_HOOK_MODE_DECLTMP, (val)   
2033 +#define AP_HOOK_ALL           AP_HOOK_MODE_ALL
2034 +
2035 +/*
2036 + * Hook State Identification
2037 + */
2038 +
2039 +/* the type of the hook state */
2040 +typedef unsigned short int ap_hook_state;
2041 +
2042 +/* the values of the hook state */
2043 +#define AP_HOOK_STATE_UNDEF       0
2044 +#define AP_HOOK_STATE_NOTEXISTANT 1
2045 +#define AP_HOOK_STATE_ESTABLISHED 2
2046 +#define AP_HOOK_STATE_CONFIGURED  3
2047 +#define AP_HOOK_STATE_REGISTERED  4
2048 +
2049 +/*
2050 + * Hook Context Identification
2051 + *
2052 + * Notice: Null is ok here, because AP_HOOK_NOCTX is just a dummy argument
2053 + *         because we know from the signature whether the argument is a
2054 + *         context value or just the dummy value.
2055 + */
2056 +
2057 +#define AP_HOOK_NOCTX  (void *)(0)
2058 +#define AP_HOOK_CTX(v) (void *)(v)
2059 +
2060 +/*
2061 + * Internal Hook Record Definition
2062 + */
2063 +
2064 +/* the union holding the arbitrary decline values */
2065 +typedef union {
2066 +    char   v_char;
2067 +    int    v_int;
2068 +    long   v_long;
2069 +    float  v_float;
2070 +    double v_double;
2071 +    void  *v_ptr;
2072 +} ap_hook_value;
2073 +
2074 +/* the structure holding one hook function and its context */
2075 +typedef struct {
2076 +    void *hf_ptr;              /* function pointer       */
2077 +    void *hf_ctx;              /* function context       */
2078 +} ap_hook_func;
2079 +
2080 +/* the structure holding one hook entry with all its registered functions */
2081 +typedef struct {
2082 +    char          *he_hook;    /* hook name (=unique id) */
2083 +    ap_hook_sig    he_sig;     /* hook signature         */
2084 +    int            he_modeid;  /* hook mode id           */
2085 +    ap_hook_value  he_modeval; /* hook mode value        */
2086 +    ap_hook_func **he_func;    /* hook registered funcs  */
2087 +} ap_hook_entry;
2088 +
2089 +/* the maximum number of hooks and functions per hook */
2090 +#define AP_HOOK_MAX_ENTRIES 512
2091 +#define AP_HOOK_MAX_FUNCS   128
2092 +
2093 +/*
2094 + * Extended Variable Argument (vararg) Support
2095 + *
2096 + * In ANSI C varargs exists, but because the prototypes of function with
2097 + * varargs cannot reflect the types of the varargs, K&R argument passing
2098 + * conventions have to apply for the compiler.  This means mainly a conversion
2099 + * of shorter type variants to the maximum variant (according to sizeof). The
2100 + * above va_type() macro provides this mapping from the wanted types to the
2101 + * physically used ones.
2102 + */
2103 +
2104 +/* the mapping */
2105 +#define VA_TYPE_char   int
2106 +#define VA_TYPE_short  int
2107 +#define VA_TYPE_int    int
2108 +#define VA_TYPE_long   long
2109 +#define VA_TYPE_float  double
2110 +#define VA_TYPE_double double
2111 +#define VA_TYPE_ptr    void *
2112 +#define VA_TYPE_ctx    void *
2113 +
2114 +/* the constructor */
2115 +#ifdef  va_type
2116 +#undef  va_type
2117 +#endif
2118 +#define va_type(type)  VA_TYPE_ ## type
2119 +
2120 +/*
2121 + * Miscellaneous stuff
2122 + */
2123 +
2124 +#ifndef FALSE
2125 +#define FALSE 0
2126 +#define TRUE  !FALSE
2127 +#endif
2128 +
2129 +/*
2130 + * Wrapper macros for the callback-function register/unregister calls.  
2131 + * 
2132 + * Background: Strict ANSI C doesn't allow a function pointer to be treated as
2133 + * a void pointer on argument passing, but we cannot declare the argument as a
2134 + * function prototype, because the functions can have arbitrary signatures. So
2135 + * we have to use a void pointer here. But to not require explicit casts on
2136 + * function pointers for every register/unregister call, we smooth the API a
2137 + * little bit by providing these macros.
2138 + */
2139 +
2140 +#define ap_hook_register(hook,func,ctx) ap_hook_register_I(hook,(void *)(func),ctx)
2141 +#define ap_hook_unregister(hook,func)   ap_hook_unregister_I(hook,(void *)(func))
2142 +
2143 +/*
2144 + * Prototypes for the hook API functions
2145 + */
2146 +
2147 +API_EXPORT(void)          ap_hook_init         (void);
2148 +API_EXPORT(void)          ap_hook_kill         (void);
2149 +API_EXPORT(int)           ap_hook_configure    (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);
2150 +API_EXPORT(int)           ap_hook_register_I   (char *hook, void *func, void *ctx);
2151 +API_EXPORT(int)           ap_hook_unregister_I (char *hook, void *func);
2152 +API_EXPORT(ap_hook_state) ap_hook_status       (char *hook);
2153 +API_EXPORT(int)           ap_hook_use          (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);
2154 +API_EXPORT(int)           ap_hook_call         (char *hook, ...);
2155 +
2156 +#endif /* AP_HOOK_H */
2157 +
2158 +#endif /* EAPI */
2159 +/*
2160 +=pod
2161 +##
2162 +##  Embedded POD document
2163 +##
2164 +
2165 +=head1 NAME
2166 +
2167 +B<ap_hook> - B<Generic Hook Interface for Apache>
2168 +
2169 +=head1 SYNOPSIS
2170 +
2171 +B<Hook Library Setup:>
2172 +
2173 + void ap_hook_init(void);
2174 + void ap_hook_kill(void);
2175 +
2176 +B<Hook Configuration and Registration:>
2177 +
2178 + int ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode mode);
2179 + int ap_hook_register(char *hook, void *func, void *ctx);
2180 + int ap_hook_unregister(char *hook, void *func);
2181 +
2182 +B<Hook Usage:>
2183 +
2184 + ap_hook_state ap_hook_status(char *hook);
2185 + int ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode mode, ...);
2186 + int ap_hook_call(char *hook, ...);
2187 +
2188 +B<Hook Signature Constructors> (ap_hook_sig):
2189 +
2190 + AP_HOOK_SIG1(rc)
2191 + AP_HOOK_SIG2(rc,a1)
2192 + AP_HOOK_SIG3(rc,a1,a2)
2193 + AP_HOOK_SIG4(rc,a1,a2,a3)
2194 + AP_HOOK_SIG5(rc,a1,a2,a3,a4)
2195 + AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5)
2196 + AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6)
2197 + AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7)
2198 +
2199 +B<Hook Modes Constructors> (ap_hook_mode):
2200 +
2201 + AP_HOOK_TOPMOST
2202 + AP_HOOK_DECLINE(value)
2203 + AP_HOOK_DECLTMP(value)
2204 + AP_HOOK_ALL
2205 +
2206 +B<Hook States> (ap_hook_state):
2207 +
2208 + AP_HOOK_STATE_UNDEF
2209 + AP_HOOK_STATE_NOTEXISTANT
2210 + AP_HOOK_STATE_ESTABLISHED
2211 + AP_HOOK_STATE_CONFIGURED 
2212 + AP_HOOK_STATE_REGISTERED
2213 +
2214 +=head1 DESCRIPTION
2215 +
2216 +This library implements a generic hook interface for Apache which can be used
2217 +to loosely couple code through arbitrary hooks. There are two use cases for
2218 +this mechanism:
2219 +
2220 +=over 3
2221 +
2222 +=item B<1. Extension and Overrides>
2223 +
2224 +Inside a specific code section you want to perform a specific function call
2225 +for extension reasons.  But you want to allow one or more modules to implement
2226 +this function by registering hooks. Those hooks are registered on a stack and
2227 +can be even configured to have a I<decline> return value. As long as there are
2228 +functions which return the decline value the next function on the stack is
2229 +tried. When the first function doesn't return the decline value the hook call
2230 +stops. 
2231 +
2232 +The original intent of this use case is to provide a flexible extension
2233 +mechanism where modules can override functionality.
2234 +
2235 +=item B<2. Intercommunication>
2236 +
2237 +Inside a specific code you have a function you want to export. But you first
2238 +want to allow other code to override this function.  And second you want to
2239 +export this function without real object file symbol references. Instead you
2240 +want to register the function and let the users call this function by name. 
2241 +
2242 +The original intent of this use case is to allow inter-module communication
2243 +without direct symbol references, which are a big I<no-no> for the I<Dynamic
2244 +Shared Object> (DSO) situation.
2245 +
2246 +=back
2247 +
2248 +And the following design goals existed:
2249 +
2250 +=over 3
2251 +
2252 +=item B<1. Minimum code changes>
2253 +
2254 +The hook calls should look very similar to the corresponding direct function
2255 +call to allow one to easily translate it. And the total amount of changes for
2256 +the hook registration, hook configuration and hook usage should be as small as
2257 +possible to minimize the total code changes. Additionally a shorthand API
2258 +function (ap_hook_use) should be provided which lets one trivially add a hook
2259 +by just changing the code at a single location.
2260 +
2261 +=item B<2. The hook call has to be maximum flexible>
2262 +
2263 +In order to avoid nasty hacks, maximum flexiblity for the hook calls is
2264 +needed, i.e. any function signature (the set of types for the return value and
2265 +the arguments) should be supported.  And it should be possible to
2266 +register always a context (ctx) variable with a function which is passed to
2267 +the corresponding function when the hook call is performed.
2268 +
2269 +=back
2270 +
2271 +The implementation of this library directly followed these two design goals.
2272 +
2273 +=head1 USAGE
2274 +
2275 +Using this hook API is a four-step process:
2276 +
2277 +=over 3
2278 +
2279 +=item B<1. Initialization>
2280 +
2281 +Initialize or destroy the hook mechanism inside your application program:
2282 +
2283 + ap_hook_init();
2284 +    :
2285 + ap_hook_kill();
2286 +
2287 +=item B<2. Configuration>
2288 +
2289 +Configure a particular hook by specifing its name, signature and return type
2290 +semantic:
2291 +
2292 + ap_hook_configure("lookup", AP_HOOK_SIG2(ptr,ptr,ctx), AP_HOOK_DECLINE(NULL));
2293 + ap_hook_configure("setup", AP_HOOK_SIG2(int,ptr,char), AP_HOOK_DECLTMP(FALSE));
2294 + ap_hook_configure("read", AP_HOOK_SIG2(void,ptr), AP_HOOK_TOPMOST);
2295 + ap_hook_configure("logit", AP_HOOK_SIG2(void,ptr), AP_HOOK_ALL);
2296 +
2297 +This configures four hooks: 
2298 +
2299 +A hook named C<lookup> with the signature C<void *lookup(void *, void *)>
2300 +(where the second argument is C<NULL> or the private context pointer of the
2301 +hook function which can be optionally provided at the registration step
2302 +later) and a return code semantic which says: Proceed as long as the
2303 +registered lookup functions return C<NULL> or no more registered functions
2304 +exists. A call for this hook has to provide 2 argument only (a pointer to the
2305 +return variable and the first argument), because the context is
2306 +implicitly provided by the hook mechanism. Sample idea: I<The first function
2307 +who was successful in looking up a variable provides the value>.
2308 +
2309 +A hook named C<setup> with the signature C<int setup(void *, char)" and a
2310 +return code semantic equal to the one of the C<lookup> hook. But the decline
2311 +return value is implemented by a temporay variable of the hook mechanism and
2312 +only used for the decline decision. So a call to this hook has to provide 2
2313 +arguments only (the first and second argument, but no address to a return
2314 +value). Sample idea: I<Any function can handle the setup and when one
2315 +function handled it stops the processing by indicating this with the return
2316 +value>.
2317 +
2318 +A hook named C<read> with the signature C<void read(void *)> and a return code
2319 +semantic which says: Only the top most function on the registered function
2320 +stack is tried (and independet of a possible return value in non-void
2321 +context). A call to this hook has to provide exactly 1 argument (the
2322 +single argument to the hook function). Sample idea: I<We want to
2323 +use a read function and allow others to override it, but independent how much
2324 +registered functions exists, only top most (= last registered) function
2325 +overrides and is used>.
2326 +
2327 +A hook named C<logit> with the signature C<void logit(void *)> and a return
2328 +code semantic which says: All registered functions on the hook functioin stack
2329 +are tried. Sample idea: I<We pass a FILE pointer to the logging functions and
2330 +any function can log whatever it wants>.
2331 +
2332 +=item B<3. Registration>
2333 +
2334 +Register the actual functions which should be used by the hook:
2335 +
2336 + ap_hook_register("lookup", mylookup, mycontext);
2337 + ap_hook_register("setup", mysetup);
2338 + ap_hook_register("read", myread);
2339 + ap_hook_register("logit", mylogit);
2340 +
2341 +This registers the function C<mylookup()> under the C<lookup> hook with the
2342 +private context given by the variable C<mycontext>. And it registers the
2343 +function C<mysetup()> under the C<setup> hook without any context. Same for
2344 +C<myread> and C<mylogit>.
2345 +
2346 +=item B<4. Usage>
2347 +
2348 +Finally use the hooks, i.e. instead of using direct function calls like
2349 +        
2350 + rc = mylookup(a1, a2);
2351 + rc = mysetup(a1, a2);
2352 + myread(a1);
2353 + mylogit(a1);
2354 +
2355 +you now use:
2356 +
2357 + ap_hook_call("lookup", &rc, a1, a2);
2358 + ap_hook_call("setup", &rc, a1, a2);
2359 + ap_hook_call("read", a1);
2360 + ap_hook_call("logit", a1);
2361 +
2362 +which are internally translated to:
2363 +
2364 + rc = mylookup(a1, a2, mycontext);
2365 + rc = mysetup(a1, a2);
2366 + myread(a1);
2367 + mylogit(a1);
2368 +
2369 +Notice two things here: First the context (C<mycontext>) for the C<mylookup()>
2370 +function is automatically added by the hook mechanism. And it is a different
2371 +(and not fixed) context for each registered function, of course.  Second,
2372 +return values always have to be pushed into variables and a pointer to them
2373 +has to be given as the second argument to C<ap_hook_call> (except for
2374 +functions which have a void return type, of course).
2375 +
2376 +BTW, the return value of C<ap_hook_call()> is always C<TRUE> or C<FALSE>.
2377 +C<TRUE> when at least one function call was successful (always the case for
2378 +C<AP_HOOK_TOPMOST> and C<AP_HOOK_ALL>). C<FALSE> when all functions
2379 +returned the decline value or no functions are registered at all.
2380 +
2381 +=back
2382 +
2383 +=head1 RESTRICTIONS
2384 +
2385 +To make the hook implementation efficient and to not bloat up the code too
2386 +much a few restrictions have to make:
2387 +
2388 +=over 3
2389 +
2390 +=item 1.
2391 +
2392 +Only function calls with up to 4 arguments are implemented. When more are
2393 +needed you can either extend the hook implementation by using more bits for
2394 +the signature configuration or you can do a workaround when the function is
2395 +your own one: Put the remaining (N-4-1) arguments into a structure and pass
2396 +only a pointer (one argument) as the forth argument.
2397 +
2398 +=item 2.
2399 +
2400 +Only the following ANSI C variable types are supported:
2401 +
2402 + - For the return value: 
2403 +   void (= none), char, int, float, double, ptr (= void *)
2404 + - For the arguments:
2405 +   ctx  (= context), char, int, float, double, ptr (= void *)
2406 +
2407 +This means in theory that 6^5 (=7776) signature combinations are possible. But
2408 +because we don't need all of them inside Apache and it would bloat up the code
2409 +too dramatically we implement only a subset of those combinations. The
2410 +implemented signatures can be specified inside C<ap_hook.c> and the
2411 +corresponding code can be automatically generated by running ``C<perl
2412 +ap_hook.c>'' (yeah, no joke ;-).  So when you need a hook with a different
2413 +still not implemented signature you either have to again use a workaround as
2414 +above (i.e. use a structure) or just add the signature to the C<ap_hook.c>
2415 +file.
2416 +
2417 +=head1 EXAMPLE
2418 +
2419 +We want to call `C<ssize_t read(int, void *, size_t)>' through hooks in order
2420 +to allow modules to override this call.  So, somewhere we have a replacement
2421 +function for C<read()> defined (same signature, of course):
2422 +
2423 + ssize_t my_read(int, void *, size_t);
2424 +
2425 +We now configure a C<read> hook. Here the C<AP_HOOK_SIGx()> macro defines the
2426 +signature of the C<read()>-like callback functions and has to match the
2427 +prototype of C<read()>. But we have to replace typedefs with the physical
2428 +underlaying ANSI C types. And C<AP_HOOK_DECLINE()> sets the return value of
2429 +the read()-like functions which forces the next hook to be called (here -1).
2430 +And we register the original C<read()> function as the default hook.
2431 +
2432 + ap_hook_configure("read", 
2433 +                   AP_HOOK_SIG4(int,int,ptr,int), 
2434 +                   AP_HOOK_DECLINE(-1));
2435 + ap_hook_register("read", read);
2436 +
2437 +Now a module wants to override the C<read()> call and registers the
2438 +C<my_read()> function:
2439 +
2440 + ap_hook_register("read", my_read);
2441 +
2442 +The function logically gets pushed onto a stack, so the execution order is the
2443 +reverse registering order, i.e. I<last registered - first called>. Now we can
2444 +replace the standard C<read()> call
2445 +
2446 + bytes = read(fd, buf, bufsize);
2447 + if (bytes == -1)
2448 +    ...error...
2449 +
2450 +with the hook based call:
2451 +
2452 +  rc = ap_hook_call("read", &bytes, fd, buf, bufsize);
2453 +  if (rc == FALSE)
2454 +     ...error...
2455 +
2456 +Now internally the following is done: The call `C<bytes = my_read(fd, buf,
2457 +bufsize)>' is done. When it returns not -1 (the decline value) nothing
2458 +more is done. But when C<my_read()> returns -1 the next function is tried:
2459 +`C<bytes = read(fd, buf, bufsize)>'. When this one also returns -1 you get
2460 +`rc == FALSE'. When it finally returns not -1 you get `rc == TRUE'.
2461 +
2462 +=head1 SEE ALSO
2463 +
2464 +ap_ctx(3)
2465 +
2466 +=head1 HISTORY
2467 +
2468 +The ap_hook(3) interface was originally designed and 
2469 +implemented in October 1998 by Ralf S. Engelschall.
2470 +
2471 +=head1 AUTHOR
2472 +
2473 + Ralf S. Engelschall
2474 + rse@engelschall.com
2475 + www.engelschall.com
2476 +
2477 +=cut
2478 +*/
2479 diff -urN apache_1.3.14.orig/src/include/ap_mm.h apache_1.3.14/src/include/ap_mm.h
2480 --- apache_1.3.14.orig/src/include/ap_mm.h      Thu Jan  1 01:00:00 1970
2481 +++ apache_1.3.14/src/include/ap_mm.h   Sat Nov 11 20:49:14 2000
2482 @@ -0,0 +1,130 @@
2483 +/* ====================================================================
2484 + * Copyright (c) 1999-2000 The Apache Group.  All rights reserved.
2485 + *
2486 + * Redistribution and use in source and binary forms, with or without
2487 + * modification, are permitted provided that the following conditions
2488 + * are met:
2489 + *
2490 + * 1. Redistributions of source code must retain the above copyright
2491 + *    notice, this list of conditions and the following disclaimer. 
2492 + *
2493 + * 2. Redistributions in binary form must reproduce the above copyright
2494 + *    notice, this list of conditions and the following disclaimer in
2495 + *    the documentation and/or other materials provided with the
2496 + *    distribution.
2497 + *
2498 + * 3. All advertising materials mentioning features or use of this
2499 + *    software must display the following acknowledgment:
2500 + *    "This product includes software developed by the Apache Group
2501 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
2502 + *
2503 + * 4. The names "Apache Server" and "Apache Group" must not be used to
2504 + *    endorse or promote products derived from this software without
2505 + *    prior written permission. For written permission, please contact
2506 + *    apache@apache.org.
2507 + *
2508 + * 5. Products derived from this software may not be called "Apache"
2509 + *    nor may "Apache" appear in their names without prior written
2510 + *    permission of the Apache Group.
2511 + *
2512 + * 6. Redistributions of any form whatsoever must retain the following
2513 + *    acknowledgment:
2514 + *    "This product includes software developed by the Apache Group
2515 + *    for use in the Apache HTTP server project (http://www.apache.org/)."
2516 + *
2517 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
2518 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2519 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2520 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
2521 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2522 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2523 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2524 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2525 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2526 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2527 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2528 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2529 + * ====================================================================
2530 + *
2531 + * This software consists of voluntary contributions made by many
2532 + * individuals on behalf of the Apache Group and was originally based
2533 + * on public domain software written at the National Center for
2534 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
2535 + * For more information on the Apache Group and the Apache HTTP server
2536 + * project, please see <http://www.apache.org/>.
2537 + */
2538 +
2539 +/*
2540 +**
2541 +** ap_mm.h -- wrapper code for MM shared memory library
2542 +**
2543 +*/
2544 +
2545 +#ifdef EAPI
2546 +
2547 +#ifndef AP_MM_H 
2548 +#define AP_MM_H 1
2549 +
2550 +#ifndef FALSE
2551 +#define FALSE 0
2552 +#define TRUE  !FALSE
2553 +#endif
2554 +
2555 +API_EXPORT(int) ap_mm_useable(void);
2556 +
2557 +typedef void AP_MM;
2558 +typedef enum { AP_MM_LOCK_RD, AP_MM_LOCK_RW } ap_mm_lock_mode;
2559 +
2560 +/* Global Malloc-Replacement API */
2561 +API_EXPORT(int)     ap_MM_create(size_t size, char *file);
2562 +API_EXPORT(int)     ap_MM_permission(mode_t mode, uid_t owner, gid_t group);
2563 +API_EXPORT(void)    ap_MM_destroy(void);
2564 +API_EXPORT(int)     ap_MM_lock(ap_mm_lock_mode mode);
2565 +API_EXPORT(int)     ap_MM_unlock(void);
2566 +API_EXPORT(void *)  ap_MM_malloc(size_t size);
2567 +API_EXPORT(void *)  ap_MM_realloc(void *ptr, size_t size);
2568 +API_EXPORT(void)    ap_MM_free(void *ptr);
2569 +API_EXPORT(void *)  ap_MM_calloc(size_t number, size_t size);
2570 +API_EXPORT(char *)  ap_MM_strdup(const char *str);
2571 +API_EXPORT(size_t)  ap_MM_sizeof(void *ptr);
2572 +API_EXPORT(size_t)  ap_MM_maxsize(void);
2573 +API_EXPORT(size_t)  ap_MM_available(void);
2574 +API_EXPORT(char *)  ap_MM_error(void);
2575 +
2576 +/* Standard Malloc-Style API */
2577 +API_EXPORT(AP_MM *) ap_mm_create(size_t size, char *file);
2578 +API_EXPORT(int)     ap_mm_permission(AP_MM *mm, mode_t mode, uid_t owner, gid_t group);
2579 +API_EXPORT(void)    ap_mm_destroy(AP_MM *mm);
2580 +API_EXPORT(int)     ap_mm_lock(AP_MM *mm, ap_mm_lock_mode mode);
2581 +API_EXPORT(int)     ap_mm_unlock(AP_MM *mm);
2582 +API_EXPORT(void *)  ap_mm_malloc(AP_MM *mm, size_t size);
2583 +API_EXPORT(void *)  ap_mm_realloc(AP_MM *mm, void *ptr, size_t size);
2584 +API_EXPORT(void)    ap_mm_free(AP_MM *mm, void *ptr);
2585 +API_EXPORT(void *)  ap_mm_calloc(AP_MM *mm, size_t number, size_t size);
2586 +API_EXPORT(char *)  ap_mm_strdup(AP_MM *mm, const char *str);
2587 +API_EXPORT(size_t)  ap_mm_sizeof(AP_MM *mm, void *ptr);
2588 +API_EXPORT(size_t)  ap_mm_maxsize(void);
2589 +API_EXPORT(size_t)  ap_mm_available(AP_MM *mm);
2590 +API_EXPORT(char *)  ap_mm_error(void);
2591 +API_EXPORT(void)    ap_mm_display_info(AP_MM *mm);
2592 +
2593 +/* Low-Level Shared Memory API */
2594 +API_EXPORT(void *)  ap_mm_core_create(size_t size, char *file);
2595 +API_EXPORT(int)     ap_mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group);
2596 +API_EXPORT(void)    ap_mm_core_delete(void *core);
2597 +API_EXPORT(size_t)  ap_mm_core_size(void *core);
2598 +API_EXPORT(int)     ap_mm_core_lock(void *core, ap_mm_lock_mode mode);
2599 +API_EXPORT(int)     ap_mm_core_unlock(void *core);
2600 +API_EXPORT(size_t)  ap_mm_core_maxsegsize(void);
2601 +API_EXPORT(size_t)  ap_mm_core_align2page(size_t size);
2602 +API_EXPORT(size_t)  ap_mm_core_align2word(size_t size);
2603 +
2604 +/* Internal Library API */
2605 +API_EXPORT(void)    ap_mm_lib_error_set(unsigned int, const char *str);
2606 +API_EXPORT(char *)  ap_mm_lib_error_get(void);
2607 +API_EXPORT(int)     ap_mm_lib_version(void);
2608 +
2609 +#endif /* AP_MM_H */
2610 +
2611 +#endif /* EAPI */
2612 +
2613 diff -urN apache_1.3.14.orig/src/include/ap_mmn.h apache_1.3.14/src/include/ap_mmn.h
2614 --- apache_1.3.14.orig/src/include/ap_mmn.h     Tue Oct  3 18:39:38 2000
2615 +++ apache_1.3.14/src/include/ap_mmn.h  Sat Nov 11 20:49:14 2000
2616 @@ -232,7 +232,23 @@
2617   * 19990320.10          - add ap_is_rdirectory() and ap_stripprefix()
2618   */
2619  
2620 +/* 
2621 + * Under Extended API situations we replace the magic cookie "AP13" with
2622 + * "EAPI" to let us distinguish between the EAPI module structure (which
2623 + * contain additional pointers at the end) and standard module structures
2624 + * (which lack at least NULL's for the pointers at the end).  This is
2625 + * important because standard ("AP13") modules would dump core when we
2626 + * dispatch over the additional hooks because NULL's are missing at the end of
2627 + * the module structure. See also the code in mod_so for details on loading
2628 + * (we accept both "AP13" and "EAPI").
2629 + */
2630 +#ifdef EAPI
2631 +#define MODULE_MAGIC_COOKIE_AP13 0x41503133UL /* "AP13" */
2632 +#define MODULE_MAGIC_COOKIE_EAPI 0x45415049UL /* "EAPI" */
2633 +#define MODULE_MAGIC_COOKIE      MODULE_MAGIC_COOKIE_EAPI 
2634 +#else
2635  #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
2636 +#endif
2637  
2638  #ifndef MODULE_MAGIC_NUMBER_MAJOR
2639  #define MODULE_MAGIC_NUMBER_MAJOR 19990320
2640 diff -urN apache_1.3.14.orig/src/include/buff.h apache_1.3.14/src/include/buff.h
2641 --- apache_1.3.14.orig/src/include/buff.h       Fri Jan  1 20:04:39 1999
2642 +++ apache_1.3.14/src/include/buff.h    Sat Nov 11 20:49:14 2000
2643 @@ -124,6 +124,10 @@
2644      /* transport handle, for RPC binding handle or some such */
2645      void *t_handle;
2646  
2647 +#ifdef EAPI
2648 +    ap_ctx *ctx;
2649 +#endif /* EAPI */
2650 +
2651  #ifdef B_SFIO
2652      Sfio_t *sf_in;
2653      Sfio_t *sf_out;
2654 @@ -175,6 +179,10 @@
2655  /* Internal routines */
2656  API_EXPORT(int) ap_bflsbuf(int c, BUFF *fb);
2657  API_EXPORT(int) ap_bfilbuf(BUFF *fb);
2658 +
2659 +#ifdef EAPI
2660 +#define ap_bpeekc(fb) ( ((fb)->incnt == 0) ? EOF : *((fb)->inptr) )
2661 +#endif
2662  
2663  #ifndef CHARSET_EBCDIC
2664  
2665 diff -urN apache_1.3.14.orig/src/include/http_conf_globals.h apache_1.3.14/src/include/http_conf_globals.h
2666 --- apache_1.3.14.orig/src/include/http_conf_globals.h  Tue Oct 10 15:21:20 2000
2667 +++ apache_1.3.14/src/include/http_conf_globals.h       Sat Nov 11 20:49:14 2000
2668 @@ -91,6 +91,9 @@
2669  extern int ap_listenbacklog;
2670  extern int ap_dump_settings;
2671  extern API_VAR_EXPORT int ap_extended_status;
2672 +#ifdef EAPI
2673 +extern API_VAR_EXPORT ap_ctx *ap_global_ctx;
2674 +#endif /* EAPI */
2675  
2676  extern API_VAR_EXPORT char *ap_pid_fname;
2677  extern API_VAR_EXPORT char *ap_scoreboard_fname;
2678 diff -urN apache_1.3.14.orig/src/include/http_config.h apache_1.3.14/src/include/http_config.h
2679 --- apache_1.3.14.orig/src/include/http_config.h        Fri Jun  2 01:42:23 2000
2680 +++ apache_1.3.14/src/include/http_config.h     Sat Nov 11 20:49:14 2000
2681 @@ -275,6 +275,65 @@
2682      void (*child_exit) (server_rec *, pool *);
2683  #endif
2684      int (*post_read_request) (request_rec *);
2685 +
2686 +#ifdef EAPI
2687 +    /*
2688 +     * ANSI C guarantees us that we can at least _extend_ the module structure
2689 +     * with additional hooks without the need to change all existing modules.
2690 +     * Because: ``If there are fewer initializers in the list than members of
2691 +     * the structure, the trailing members are initialized with 0.'' (The C
2692 +     * Programming Language, 2nd Ed., A8.7 Initialization). So we just
2693 +     * have to put our additional hooks here:
2694 +     *
2695 +     * add_module: 
2696 +     *     Called from within ap_add_module() right after the module structure
2697 +     *     was linked into the Apache internal module list.  It is mainly
2698 +     *     intended to be used to define configuration defines (<IfDefine>)
2699 +     *     which have to be available directly after a LoadModule/AddModule.
2700 +     *     Actually this is the earliest possible hook a module can use.
2701 +     *
2702 +     * remove_module: 
2703 +     *     Called from within ap_remove_module() right before the module
2704 +     *     structure is kicked out from the Apache internal module list.
2705 +     *     Actually this is last possible hook a module can use and exists for
2706 +     *     consistency with the add_module hook.
2707 +     *
2708 +     * rewrite_command:
2709 +     *     Called right after a configuration directive line was read and
2710 +     *     before it is processed. It is mainly intended to be used for
2711 +     *     rewriting directives in order to provide backward compatibility to
2712 +     *     old directive variants.
2713 +     *
2714 +     * new_connection:
2715 +     *     Called from within the internal new_connection() function, right
2716 +     *     after the conn_rec structure for the new established connection was
2717 +     *     created and before Apache starts processing the request with
2718 +     *     ap_read_request().  It is mainly intended to be used to setup/run
2719 +     *     connection dependent things like sending start headers for
2720 +     *     on-the-fly compression, etc.
2721 +     *
2722 +     * close_connection:
2723 +     *     Called from within the Apache dispatching loop just before any
2724 +     *     ap_bclose() is performed on the socket connection, but a long time
2725 +     *     before any pool cleanups are done for the connection (which can be
2726 +     *     too late for some applications).  It is mainly intended to be used
2727 +     *     to close/finalize connection dependent things like sending end
2728 +     *     headers for on-the-fly compression, etc.
2729 +     */
2730 +#ifdef ULTRIX_BRAIN_DEATH
2731 +    void  (*add_module) ();
2732 +    void  (*remove_module) ();
2733 +    char *(*rewrite_command) ();
2734 +    void  (*new_connection) ();
2735 +    void  (*close_connection) ();
2736 +#else
2737 +    void  (*add_module) (struct module_struct *);
2738 +    void  (*remove_module) (struct module_struct *);
2739 +    char *(*rewrite_command) (cmd_parms *, void *config, const char *);
2740 +    void  (*new_connection) (conn_rec *);
2741 +    void  (*close_connection) (conn_rec *);
2742 +#endif
2743 +#endif /* EAPI */
2744  } module;
2745  
2746  /* Initializer for the first few module slots, which are only
2747 diff -urN apache_1.3.14.orig/src/include/http_main.h apache_1.3.14/src/include/http_main.h
2748 --- apache_1.3.14.orig/src/include/http_main.h  Thu Jun 15 21:18:26 2000
2749 +++ apache_1.3.14/src/include/http_main.h       Sat Nov 11 20:49:14 2000
2750 @@ -124,7 +124,11 @@
2751  API_EXPORT(void) ap_sync_scoreboard_image(void);
2752  int ap_update_child_status(int child_num, int status, request_rec *r);
2753  void ap_time_process_request(int child_num, int status);
2754 +#ifdef EAPI
2755 +API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x);
2756 +#else
2757  unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x);
2758 +#endif
2759  API_EXPORT(int) ap_check_alarm(void);
2760  
2761  void setup_signal_names(char *prefix);
2762 diff -urN apache_1.3.14.orig/src/include/httpd.h apache_1.3.14/src/include/httpd.h
2763 --- apache_1.3.14.orig/src/include/httpd.h      Tue Oct 10 22:13:03 2000
2764 +++ apache_1.3.14/src/include/httpd.h   Sat Nov 11 20:57:42 2000
2765 @@ -69,7 +69,19 @@
2766  /* Headers in which EVERYONE has an interest... */
2767  
2768  #include "ap_config.h"
2769 +#ifdef EAPI
2770 +#include "ap_mm.h"
2771 +#endif
2772  #include "ap_alloc.h"
2773 +/*
2774 + * Include the Extended API headers.
2775 + * Don't move the position. It has to be after alloc.h because it uses the
2776 + * pool stuff but before buff.h because the buffer stuff uses the EAPI, too. 
2777 + */
2778 +#ifdef EAPI
2779 +#include "ap_hook.h"
2780 +#include "ap_ctx.h"
2781 +#endif /* EAPI */
2782  #include "buff.h"
2783  #include "ap.h"
2784  
2785 @@ -140,8 +152,13 @@
2786  #define DEFAULT_HTTP_PORT      80
2787  #define DEFAULT_HTTPS_PORT     443
2788  #define ap_is_default_port(port,r)     ((port) == ap_default_port(r))
2789 +#ifdef EAPI
2790 +#define ap_http_method(r)   (ap_ctx_get((r)->ctx, "ap::http::method") != NULL ? ((char *)ap_ctx_get((r)->ctx, "ap::http::method")) : "http")
2791 +#define ap_default_port(r)  (ap_ctx_get((r)->ctx, "ap::default::port") != NULL ? atoi((char *)ap_ctx_get((r)->ctx, "ap::default::port")) : DEFAULT_HTTP_PORT)
2792 +#else /* EAPI */
2793  #define ap_http_method(r)      "http"
2794  #define ap_default_port(r)     DEFAULT_HTTP_PORT
2795 +#endif /* EAPI */
2796  
2797  /* --------- Default user name and group name running standalone ---------- */
2798  /* --- These may be specified as numbers by placing a # before a number --- */
2799 @@ -353,6 +370,19 @@
2800  #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
2801  #endif
2802  
2803 +/*
2804 + * Unix only:
2805 + * Path to Shared Memory Files 
2806 + */
2807 +#ifdef EAPI
2808 +#ifndef EAPI_MM_CORE_PATH
2809 +#define EAPI_MM_CORE_PATH "logs/mm"
2810 +#endif
2811 +#ifndef EAPI_MM_CORE_MAXSIZE
2812 +#define EAPI_MM_CORE_MAXSIZE 1024*1024*1 /* max. 1MB */
2813 +#endif
2814 +#endif
2815 +
2816  /* Number of requests to try to handle in a single process.  If <= 0,
2817   * the children don't die off.  That's the default here, since I'm still
2818   * interested in finding and stanching leaks.
2819 @@ -445,6 +475,9 @@
2820  API_EXPORT(const char *) ap_get_server_version(void);
2821  API_EXPORT(void) ap_add_version_component(const char *component);
2822  API_EXPORT(const char *) ap_get_server_built(void);
2823 +#ifdef EAPI
2824 +API_EXPORT(void) ap_add_config_define(const char *define);
2825 +#endif /* EAPI */
2826  
2827  /* Numeric release version identifier: MMNNFFRBB: major minor fix final beta
2828   * Always increases along the same track as the source branch.
2829 @@ -837,6 +870,10 @@
2830   * record to improve 64bit alignment the next time we need to break
2831   * binary compatibility for some other reason.
2832   */
2833 +
2834 +#ifdef EAPI
2835 +    ap_ctx *ctx;
2836 +#endif /* EAPI */
2837  };
2838  
2839  
2840 @@ -885,6 +922,9 @@
2841      char *local_host;          /* used for ap_get_server_name when
2842                                  * UseCanonicalName is set to DNS
2843                                  * (ignores setting of HostnameLookups) */
2844 +#ifdef EAPI
2845 +    ap_ctx *ctx;
2846 +#endif /* EAPI */
2847  };
2848  
2849  /* Per-vhost config... */
2850 @@ -957,6 +997,10 @@
2851      int limit_req_line;      /* limit on size of the HTTP request line    */
2852      int limit_req_fieldsize; /* limit on size of any request header field */
2853      int limit_req_fields;    /* limit on number of request header fields  */
2854 +
2855 +#ifdef EAPI
2856 +    ap_ctx *ctx;
2857 +#endif /* EAPI */
2858  };
2859  
2860  /* These are more like real hosts than virtual hosts */
2861 diff -urN apache_1.3.14.orig/src/main/alloc.c apache_1.3.14/src/main/alloc.c
2862 --- apache_1.3.14.orig/src/main/alloc.c Fri Jul 14 16:17:35 2000
2863 +++ apache_1.3.14/src/main/alloc.c      Sat Nov 11 20:49:14 2000
2864 @@ -63,6 +63,10 @@
2865   */
2866  
2867  #include "httpd.h"
2868 +#ifdef EAPI
2869 +#include "http_config.h"
2870 +#include "http_conf_globals.h"
2871 +#endif
2872  #include "multithread.h"
2873  #include "http_log.h"
2874  
2875 @@ -137,6 +141,10 @@
2876  #define BLOCK_MINALLOC 0
2877  #endif
2878  
2879 +#if defined(EAPI) && defined(EAPI_MM)
2880 +static AP_MM *mm = NULL;
2881 +#endif
2882 +
2883  /*****************************************************************
2884   *
2885   * Managing free storage blocks...
2886 @@ -165,6 +173,9 @@
2887         char *endp;
2888         union block_hdr *next;
2889         char *first_avail;
2890 +#if defined(EAPI) && defined(EAPI_MM)
2891 +       int is_shm;
2892 +#endif
2893  #ifdef POOL_DEBUG
2894         union block_hdr *global_next;
2895         struct pool *owning_pool;
2896 @@ -215,7 +226,11 @@
2897  /* Get a completely new block from the system pool. Note that we rely on
2898     malloc() to provide aligned memory. */
2899  
2900 +#if defined(EAPI) && defined(EAPI_MM)
2901 +static union block_hdr *malloc_block(int size, int is_shm)
2902 +#else
2903  static union block_hdr *malloc_block(int size)
2904 +#endif
2905  {
2906      union block_hdr *blok;
2907  
2908 @@ -229,12 +244,20 @@
2909      ++num_malloc_calls;
2910      num_malloc_bytes += size + sizeof(union block_hdr);
2911  #endif
2912 +#if defined(EAPI) && defined(EAPI_MM)
2913 +    if (is_shm)
2914 +        blok = (union block_hdr *)ap_mm_malloc(mm, size + sizeof(union block_hdr));
2915 +    else
2916 +#endif
2917      blok = (union block_hdr *) malloc(size + sizeof(union block_hdr));
2918      if (blok == NULL) {
2919         fprintf(stderr, "Ouch!  malloc failed in malloc_block()\n");
2920         exit(1);
2921      }
2922      debug_fill(blok, size + sizeof(union block_hdr));
2923 +#if defined(EAPI) && defined(EAPI_MM)
2924 +    blok->h.is_shm = is_shm;
2925 +#endif
2926      blok->h.next = NULL;
2927      blok->h.first_avail = (char *) (blok + 1);
2928      blok->h.endp = size + blok->h.first_avail;
2929 @@ -295,6 +318,10 @@
2930      if (blok == NULL)
2931         return;                 /* Sanity check --- freeing empty pool? */
2932  
2933 +#if defined(EAPI) && defined(EAPI_MM)
2934 +    if (blok->h.is_shm)
2935 +        (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
2936 +#endif
2937      (void) ap_acquire_mutex(alloc_mutex);
2938      old_free_list = block_freelist;
2939      block_freelist = blok;
2940 @@ -341,6 +368,10 @@
2941  #endif
2942  
2943      (void) ap_release_mutex(alloc_mutex);
2944 +#if defined(EAPI) && defined(EAPI_MM)
2945 +    if (blok->h.is_shm)
2946 +        (void)ap_mm_unlock(mm);
2947 +#endif
2948  #endif
2949  }
2950  
2951 @@ -349,7 +380,11 @@
2952   * if necessary.  Must be called with alarms blocked.
2953   */
2954  
2955 +#if defined(EAPI) && defined(EAPI_MM)
2956 +static union block_hdr *new_block(int min_size, int is_shm)
2957 +#else
2958  static union block_hdr *new_block(int min_size)
2959 +#endif
2960  {
2961      union block_hdr **lastptr = &block_freelist;
2962      union block_hdr *blok = block_freelist;
2963 @@ -359,7 +394,12 @@
2964       */
2965  
2966      while (blok != NULL) {
2967 +#if defined(EAPI) && defined(EAPI_MM)
2968 +    if (blok->h.is_shm == is_shm &&
2969 +        min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
2970 +#else
2971         if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
2972 +#endif
2973             *lastptr = blok->h.next;
2974             blok->h.next = NULL;
2975             debug_verify_filled(blok->h.first_avail, blok->h.endp,
2976 @@ -375,7 +415,11 @@
2977      /* Nope. */
2978  
2979      min_size += BLOCK_MINFREE;
2980 +#if defined(EAPI) && defined(EAPI_MM)
2981 +    blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC, is_shm);
2982 +#else
2983      blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
2984 +#endif
2985      return blok;
2986  }
2987  
2988 @@ -425,6 +469,9 @@
2989  #ifdef POOL_DEBUG
2990      struct pool *joined;
2991  #endif
2992 +#if defined(EAPI) && defined(EAPI_MM)
2993 +    int is_shm;
2994 +#endif
2995  };
2996  
2997  static pool *permanent_pool;
2998 @@ -439,16 +486,28 @@
2999  #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))
3000  #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)
3001  
3002 +#if defined(EAPI) && defined(EAPI_MM)
3003 +static struct pool *make_sub_pool_internal(struct pool *p, int is_shm)
3004 +#else
3005  API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
3006 +#endif
3007  {
3008      union block_hdr *blok;
3009      pool *new_pool;
3010  
3011      ap_block_alarms();
3012  
3013 +#if defined(EAPI) && defined(EAPI_MM)
3014 +    if (is_shm)
3015 +        (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3016 +#endif
3017      (void) ap_acquire_mutex(alloc_mutex);
3018  
3019 +#if defined(EAPI) && defined(EAPI_MM)
3020 +    blok = new_block(POOL_HDR_BYTES, is_shm);
3021 +#else
3022      blok = new_block(POOL_HDR_BYTES);
3023 +#endif
3024      new_pool = (pool *) blok->h.first_avail;
3025      blok->h.first_avail += POOL_HDR_BYTES;
3026  #ifdef POOL_DEBUG
3027 @@ -467,12 +526,38 @@
3028         p->sub_pools = new_pool;
3029      }
3030  
3031 +#if defined(EAPI) && defined(EAPI_MM)
3032 +    new_pool->is_shm = is_shm;
3033 +#endif
3034 +
3035      (void) ap_release_mutex(alloc_mutex);
3036 +#if defined(EAPI) && defined(EAPI_MM)
3037 +    if (is_shm)
3038 +       (void)ap_mm_unlock(mm);
3039 +#endif
3040      ap_unblock_alarms();
3041  
3042      return new_pool;
3043  }
3044  
3045 +#if defined(EAPI)
3046 +#if defined(EAPI_MM)
3047 +API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
3048 +{
3049 +    return make_sub_pool_internal(p, 0);
3050 +}
3051 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
3052 +{
3053 +    return make_sub_pool_internal(p, 1);
3054 +}
3055 +#else
3056 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
3057 +{
3058 +    return NULL;
3059 +}
3060 +#endif
3061 +#endif
3062 +
3063  #ifdef POOL_DEBUG
3064  static void stack_var_init(char *s)
3065  {
3066 @@ -487,6 +572,13 @@
3067  }
3068  #endif
3069  
3070 +#if defined(EAPI)
3071 +int ap_shared_pool_possible(void)
3072 +{
3073 +    return ap_mm_useable();
3074 +}
3075 +#endif
3076 +
3077  #ifdef ALLOC_STATS
3078  static void dump_stats(void)
3079  {
3080 @@ -525,14 +617,74 @@
3081      ap_destroy_mutex(spawn_mutex);
3082  }
3083  
3084 +#if defined(EAPI)
3085 +void ap_init_alloc_shared(int early)
3086 +{
3087 +#if defined(EAPI_MM)
3088 +    int mm_size;
3089 +    char *mm_path;
3090 +    char *err1, *err2;
3091 +
3092 +    if (early) {
3093 +        /* process very early on startup */
3094 +        mm_size = ap_mm_maxsize();
3095 +        if (mm_size > EAPI_MM_CORE_MAXSIZE)
3096 +            mm_size = EAPI_MM_CORE_MAXSIZE;
3097 +        mm_path = ap_server_root_relative(permanent_pool, 
3098 +                  ap_psprintf(permanent_pool, "%s.%ld", 
3099 +                              EAPI_MM_CORE_PATH, (long)getpid()));
3100 +        if ((mm = ap_mm_create(mm_size, mm_path)) == NULL) {
3101 +            fprintf(stderr, "Ouch! ap_mm_create(%d, \"%s\") failed\n", mm_size, mm_path);
3102 +            err1 = ap_mm_error();
3103 +            if (err1 == NULL)
3104 +                err1 = "-unknown-";
3105 +            err2 = strerror(errno);
3106 +            if (err2 == NULL)
3107 +                err2 = "-unknown-";
3108 +            fprintf(stderr, "Error: MM: %s: OS: %s\n", err1, err2);
3109 +            exit(1);
3110 +        }
3111 +    }
3112 +    else {
3113 +        /* process a lot later on startup */
3114 +#ifdef WIN32
3115 +        ap_mm_permission(mm, (_S_IREAD|_S_IWRITE), ap_user_id, -1);
3116 +#else
3117 +        ap_mm_permission(mm, (S_IRUSR|S_IWUSR), ap_user_id, -1);
3118 +#endif
3119 +    }
3120 +#endif /* EAPI_MM */
3121 +    return; 
3122 +}
3123 +
3124 +void ap_kill_alloc_shared(void)
3125 +{
3126 +#if defined(EAPI_MM)
3127 +    if (mm != NULL) {
3128 +        ap_mm_destroy(mm);
3129 +        mm = NULL;
3130 +    }
3131 +#endif /* EAPI_MM */
3132 +    return;
3133 +}
3134 +#endif /* EAPI */
3135 +
3136  API_EXPORT(void) ap_clear_pool(struct pool *a)
3137  {
3138      ap_block_alarms();
3139  
3140 +#if defined(EAPI) && defined(EAPI_MM)
3141 +    if (a->is_shm)
3142 +        (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3143 +#endif
3144      (void) ap_acquire_mutex(alloc_mutex);
3145      while (a->sub_pools)
3146         ap_destroy_pool(a->sub_pools);
3147      (void) ap_release_mutex(alloc_mutex);
3148 +#if defined(EAPI) && defined(EAPI_MM)
3149 +    if (a->is_shm)
3150 +           (void)ap_mm_unlock(mm);
3151 +#endif
3152      /* Don't hold the mutex during cleanups. */
3153      run_cleanups(a->cleanups);
3154      a->cleanups = NULL;
3155 @@ -566,6 +718,10 @@
3156      ap_block_alarms();
3157      ap_clear_pool(a);
3158  
3159 +#if defined(EAPI) && defined(EAPI_MM)
3160 +    if (a->is_shm)
3161 +       (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3162 +#endif
3163      (void) ap_acquire_mutex(alloc_mutex);
3164      if (a->parent) {
3165         if (a->parent->sub_pools == a)
3166 @@ -576,6 +732,10 @@
3167             a->sub_next->sub_prev = a->sub_prev;
3168      }
3169      (void) ap_release_mutex(alloc_mutex);
3170 +#if defined(EAPI) && defined(EAPI_MM)
3171 +    if (a->is_shm)
3172 +       (void)ap_mm_unlock(mm);
3173 +#endif
3174  
3175      free_blocks(a->first);
3176      ap_unblock_alarms();
3177 @@ -590,6 +750,30 @@
3178      return bytes_in_block_list(block_freelist);
3179  }
3180  
3181 +#if defined(EAPI)
3182 +API_EXPORT(int) ap_acquire_pool(pool *p, ap_pool_lock_mode mode)
3183 +{
3184 +#if defined(EAPI_MM)
3185 +    if (!p->is_shm)
3186 +        return 1;
3187 +    return ap_mm_lock(mm, mode == AP_POOL_RD ? AP_MM_LOCK_RD : AP_MM_LOCK_RW);
3188 +#else
3189 +       return 1;
3190 +#endif
3191 +}
3192 +
3193 +API_EXPORT(int) ap_release_pool(pool *p)
3194 +{
3195 +#if defined(EAPI_MM)
3196 +    if (!p->is_shm)
3197 +        return 1;
3198 +    return ap_mm_unlock(mm);
3199 +#else
3200 +       return 1;
3201 +#endif
3202 +}
3203 +#endif /* EAPI */
3204 +
3205  /*****************************************************************
3206   * POOL_DEBUG support
3207   */
3208 @@ -755,16 +939,31 @@
3209  
3210      ap_block_alarms();
3211  
3212 +#if defined(EAPI) && defined(EAPI_MM)
3213 +    if (a->is_shm)
3214 +       (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3215 +#endif
3216      (void) ap_acquire_mutex(alloc_mutex);
3217  
3218 +#if defined(EAPI) && defined(EAPI_MM)
3219 +    blok = new_block(size, a->is_shm);
3220 +#else
3221      blok = new_block(size);
3222 +#endif
3223      a->last->h.next = blok;
3224      a->last = blok;
3225  #ifdef POOL_DEBUG
3226      blok->h.owning_pool = a;
3227  #endif
3228 +#if defined(EAPI) && defined(EAPI_MM)
3229 +    blok->h.is_shm = a->is_shm;
3230 +#endif
3231  
3232      (void) ap_release_mutex(alloc_mutex);
3233 +#if defined(EAPI) && defined(EAPI_MM)
3234 +    if (a->is_shm)
3235 +       (void)ap_mm_unlock(mm);
3236 +#endif
3237  
3238      ap_unblock_alarms();
3239  
3240 @@ -876,6 +1075,11 @@
3241      char *ptr;
3242  
3243      size = (char *)ps->vbuff.curpos - ps->base;
3244 +#if defined(EAPI) && defined(EAPI_MM)
3245 +    if (ps->block->h.is_shm)
3246 +        ptr = ap_mm_realloc(ps->base, 2*size);
3247 +    else
3248 +#endif
3249      ptr = realloc(ps->base, 2*size);
3250      if (ptr == NULL) {
3251         fputs("Ouch!  Out of memory!\n", stderr);
3252 @@ -896,9 +1100,21 @@
3253      cur_len = strp - blok->h.first_avail;
3254  
3255      /* must try another blok */
3256 +#if defined(EAPI) && defined(EAPI_MM)
3257 +    if (blok->h.is_shm)
3258 +       (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3259 +#endif
3260      (void) ap_acquire_mutex(alloc_mutex);
3261 +#if defined(EAPI) && defined(EAPI_MM)
3262 +    nblok = new_block(2 * cur_len, blok->h.is_shm);
3263 +#else
3264      nblok = new_block(2 * cur_len);
3265 +#endif
3266      (void) ap_release_mutex(alloc_mutex);
3267 +#if defined(EAPI) && defined(EAPI_MM)
3268 +    if (blok->h.is_shm)
3269 +       (void)ap_mm_unlock(mm);
3270 +#endif
3271      memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len);
3272      ps->vbuff.curpos = nblok->h.first_avail + cur_len;
3273      /* save a byte for the NUL terminator */
3274 @@ -907,10 +1123,18 @@
3275      /* did we allocate the current blok? if so free it up */
3276      if (ps->got_a_new_block) {
3277         debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
3278 +#if defined(EAPI) && defined(EAPI_MM)
3279 +    if (blok->h.is_shm)
3280 +       (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3281 +#endif
3282         (void) ap_acquire_mutex(alloc_mutex);
3283         blok->h.next = block_freelist;
3284         block_freelist = blok;
3285         (void) ap_release_mutex(alloc_mutex);
3286 +#if defined(EAPI) && defined(EAPI_MM)
3287 +    if (blok->h.is_shm)
3288 +       (void)ap_mm_unlock(mm);
3289 +#endif
3290      }
3291      ps->blok = nblok;
3292      ps->got_a_new_block = 1;
3293 @@ -929,6 +1153,11 @@
3294      void *ptr;
3295  
3296      ap_block_alarms();
3297 +#if defined(EAPI) && defined(EAPI_MM)
3298 +    if (p->is_shm)
3299 +        ps.base = ap_mm_malloc(mm, 512);
3300 +    else
3301 +#endif
3302      ps.base = malloc(512);
3303      if (ps.base == NULL) {
3304         fputs("Ouch!  Out of memory!\n", stderr);
3305 @@ -941,6 +1170,11 @@
3306      *ps.vbuff.curpos++ = '\0';
3307      ptr = ps.base;
3308      /* shrink */
3309 +#if defined(EAPI) && defined(EAPI_MM)
3310 +    if (p->is_shm)
3311 +        ptr = ap_mm_realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
3312 +    else
3313 +#endif
3314      ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
3315      if (ptr == NULL) {
3316         fputs("Ouch!  Out of memory!\n", stderr);
3317 diff -urN apache_1.3.14.orig/src/main/buff.c apache_1.3.14/src/main/buff.c
3318 --- apache_1.3.14.orig/src/main/buff.c  Tue Sep 26 23:03:42 2000
3319 +++ apache_1.3.14/src/main/buff.c       Sat Nov 11 20:49:14 2000
3320 @@ -126,7 +126,11 @@
3321    select() sometimes returns 1 even though the write will block. We must work around this.
3322  */
3323  
3324 +#ifdef EAPI
3325 +API_EXPORT(int) sendwithtimeout(int sock, const char *buf, int len, int flags)
3326 +#else /* EAPI */
3327  int sendwithtimeout(int sock, const char *buf, int len, int flags)
3328 +#endif /* EAPI */
3329  {
3330      int iostate = 1;
3331      fd_set fdset;
3332 @@ -194,8 +198,11 @@
3333      return (rv);
3334  }
3335  
3336 -
3337 +#ifdef EAPI
3338 +API_EXPORT(int) recvwithtimeout(int sock, char *buf, int len, int flags)
3339 +#else /* EAPI */
3340  int recvwithtimeout(int sock, char *buf, int len, int flags)
3341 +#endif /* EAPI */
3342  {
3343      int iostate = 1;
3344      fd_set fdset;
3345 @@ -273,6 +280,9 @@
3346      }
3347      else
3348  #endif
3349 +#ifdef EAPI
3350 +       if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
3351 +#endif /* EAPI */
3352         rv = read(fb->fd_in, buf, nbyte);
3353      
3354      return rv;
3355 @@ -284,6 +294,9 @@
3356  
3357  #if defined (WIN32) || defined(NETWARE)
3358      if (fb->flags & B_SOCKET) {
3359 +#ifdef EAPI
3360 +       if (!ap_hook_call("ap::buff::recvwithtimeout", &rv, fb, buf, nbyte))
3361 +#endif /* EAPI */
3362         rv = recvwithtimeout(fb->fd_in, buf, nbyte, 0);
3363         if (rv == SOCKET_ERROR)
3364             errno = WSAGetLastError();
3365 @@ -331,6 +344,9 @@
3366      }
3367      else
3368  #endif
3369 +#ifdef EAPI
3370 +       if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
3371 +#endif /* EAPI */
3372  #if defined (B_SFIO)
3373         rv = sfwrite(fb->sf_out, buf, nbyte);
3374  #else
3375 @@ -357,6 +373,9 @@
3376  
3377  #if defined(WIN32) || defined(NETWARE)
3378      if (fb->flags & B_SOCKET) {
3379 +#ifdef EAPI
3380 +       if (!ap_hook_call("ap::buff::sendwithtimeout", &rv, fb, buf, nbyte))
3381 +#endif /* EAPI */
3382         rv = sendwithtimeout(fb->fd, buf, nbyte, 0);
3383         if (rv == SOCKET_ERROR)
3384             errno = WSAGetLastError();
3385 @@ -437,6 +456,10 @@
3386                        (size_t) SF_UNBOUND, 1, SF_WRITE);
3387  #endif
3388  
3389 +#ifdef EAPI
3390 +    fb->ctx = ap_ctx_new(p);
3391 +#endif /* EAPI */
3392 +
3393      return fb;
3394  }
3395  
3396 @@ -1083,6 +1106,9 @@
3397      i = 0;
3398      while (i < nvec) {
3399         do
3400 +#ifdef EAPI
3401 +           if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
3402 +#endif /* EAPI */
3403             rv = writev(fb->fd, &vec[i], nvec - i);
3404         while (rv == -1 && (errno == EINTR || errno == EAGAIN)
3405                && !(fb->flags & B_EOUT));
3406 diff -urN apache_1.3.14.orig/src/main/http_config.c apache_1.3.14/src/main/http_config.c
3407 --- apache_1.3.14.orig/src/main/http_config.c   Tue Oct  3 18:39:40 2000
3408 +++ apache_1.3.14/src/main/http_config.c        Sat Nov 11 20:49:14 2000
3409 @@ -598,6 +598,20 @@
3410         m->name = tmp;
3411      }
3412  #endif /*_OSD_POSIX*/
3413 +
3414 +#ifdef EAPI
3415 +    /*
3416 +     * Invoke the `add_module' hook inside the now existing set
3417 +     * of modules to let them all now that this module was added.
3418 +     */
3419 +    {
3420 +        module *m2;
3421 +        for (m2 = top_module; m2 != NULL; m2 = m2->next)
3422 +            if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
3423 +                if (m2->add_module != NULL)
3424 +                    (*m2->add_module)(m);
3425 +    }
3426 +#endif /* EAPI */
3427  }
3428  
3429  /* 
3430 @@ -612,6 +626,21 @@
3431  {
3432      module *modp;
3433  
3434 +#ifdef EAPI
3435 +    /*
3436 +     * Invoke the `remove_module' hook inside the now existing
3437 +     * set of modules to let them all now that this module is
3438 +     * beeing removed.
3439 +     */
3440 +    {
3441 +        module *m2;
3442 +        for (m2 = top_module; m2 != NULL; m2 = m2->next)
3443 +            if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
3444 +                if (m2->remove_module != NULL)
3445 +                    (*m2->remove_module)(m);
3446 +    }
3447 +#endif /* EAPI */
3448 +
3449      modp = top_module;
3450      if (modp == m) {
3451         /* We are the top module, special case */
3452 @@ -1005,6 +1034,27 @@
3453      const command_rec *cmd;
3454      module *mod = top_module;
3455  
3456 +#ifdef EAPI
3457 +    /*
3458 +     * Invoke the `rewrite_command' of modules to allow
3459 +     * they to rewrite the directive line before we
3460 +     * process it.
3461 +     */
3462 +    {
3463 +        module *m;
3464 +        char *cp;
3465 +        for (m = top_module; m != NULL; m = m->next) {
3466 +            if (m->magic == MODULE_MAGIC_COOKIE_EAPI) {
3467 +                if (m->rewrite_command != NULL) {
3468 +                    cp = (m->rewrite_command)(parms, config, l);
3469 +                    if (cp != NULL)
3470 +                        l = cp;
3471 +                }
3472 +            }
3473 +        }
3474 +    }
3475 +#endif /* EAPI */
3476 +
3477      if ((l[0] == '#') || (!l[0]))
3478         return NULL;
3479  
3480 @@ -1433,6 +1483,10 @@
3481      s->limit_req_fieldsize = main_server->limit_req_fieldsize;
3482      s->limit_req_fields = main_server->limit_req_fields;
3483  
3484 +#ifdef EAPI
3485 +    s->ctx = ap_ctx_new(p);
3486 +#endif /* EAPI */
3487 +
3488      *ps = s;
3489  
3490      return ap_parse_vhost_addrs(p, hostname, s);
3491 @@ -1543,6 +1597,10 @@
3492  
3493      s->module_config = create_server_config(p, s);
3494      s->lookup_defaults = create_default_per_dir_config(p);
3495 +
3496 +#ifdef EAPI
3497 +    s->ctx = ap_ctx_new(p);
3498 +#endif /* EAPI */
3499  
3500      return s;
3501  }
3502 diff -urN apache_1.3.14.orig/src/main/http_main.c apache_1.3.14/src/main/http_main.c
3503 --- apache_1.3.14.orig/src/main/http_main.c     Sat Nov 11 20:44:14 2000
3504 +++ apache_1.3.14/src/main/http_main.c  Sat Nov 11 20:53:13 2000
3505 @@ -259,6 +259,9 @@
3506  int ap_listenbacklog;
3507  int ap_dump_settings = 0;
3508  API_VAR_EXPORT int ap_extended_status = 0;
3509 +#ifdef EAPI
3510 +API_VAR_EXPORT ap_ctx *ap_global_ctx;
3511 +#endif /* EAPI */
3512  
3513  /*
3514   * The max child slot ever assigned, preserved across restarts.  Necessary
3515 @@ -444,6 +447,30 @@
3516      }
3517  }
3518  
3519 +#ifdef EAPI
3520 +API_EXPORT(void) ap_add_config_define(const char *define)
3521 +{
3522 +    char **var;
3523 +    var = (char **)ap_push_array(ap_server_config_defines);
3524 +    *var = ap_pstrdup(pcommands, define);
3525 +    return;
3526 +}
3527 +
3528 +/*
3529 + * Invoke the `close_connection' hook of modules to let them do
3530 + * some connection dependent actions before we close it.
3531 + */
3532 +static void ap_call_close_connection_hook(conn_rec *c)
3533 +{
3534 +    module *m;
3535 +    for (m = top_module; m != NULL; m = m->next)
3536 +        if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
3537 +            if (m->close_connection != NULL)
3538 +                (*m->close_connection)(c);
3539 +    return;
3540 +}
3541 +#endif /* EAPI */
3542 +
3543  #ifndef NETWARE
3544  static APACHE_TLS int volatile exit_after_unblock = 0;
3545  #endif
3546 @@ -1208,6 +1235,10 @@
3547             ap_log_transaction(log_req);
3548         }
3549  
3550 +#ifdef EAPI
3551 +       ap_call_close_connection_hook(save_req->connection);
3552 +#endif /* EAPI */
3553 +
3554         ap_bsetflag(save_req->connection->client, B_EOUT, 1);
3555         ap_bclose(save_req->connection->client);
3556         
3557 @@ -1216,6 +1247,9 @@
3558          ap_longjmp(jmpbuffer, 1);
3559      }
3560      else {                     /* abort the connection */
3561 +#ifdef EAPI
3562 +       ap_call_close_connection_hook(current_conn);
3563 +#endif /* EAPI */
3564         ap_bsetflag(current_conn->client, B_EOUT, 1);
3565         ap_bclose(current_conn->client);
3566         current_conn->aborted = 1;
3567 @@ -1281,7 +1315,11 @@
3568  }
3569  #endif
3570  
3571 +#ifdef EAPI
3572 +API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x)
3573 +#else
3574  unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x)
3575 +#endif
3576  {
3577      unsigned int old;
3578  
3579 @@ -1517,10 +1555,16 @@
3580      /* Send any leftover data to the client, but never try to again */
3581  
3582      if (ap_bflush(r->connection->client) == -1) {
3583 +#ifdef EAPI
3584 +       ap_call_close_connection_hook(r->connection);
3585 +#endif /* EAPI */
3586         ap_kill_timeout(r);
3587         ap_bclose(r->connection->client);
3588         return;
3589      }
3590 +#ifdef EAPI
3591 +    ap_call_close_connection_hook(r->connection);
3592 +#endif /* EAPI */
3593      ap_bsetflag(r->connection->client, B_EOUT, 1);
3594  
3595      /* Close our half of the connection --- send the client a FIN */
3596 @@ -2231,6 +2275,9 @@
3597      /* Clear the pool - including any registered cleanups */
3598      ap_destroy_pool(pglobal);
3599  #endif
3600 +#ifdef EAPI
3601 +    ap_kill_alloc_shared();
3602 +#endif
3603      exit(code);
3604  }
3605  
3606 @@ -3224,6 +3271,24 @@
3607      conn->remote_addr = *remaddr;
3608      conn->remote_ip = ap_pstrdup(conn->pool,
3609                               inet_ntoa(conn->remote_addr.sin_addr));
3610 +#ifdef EAPI
3611 +    conn->ctx = ap_ctx_new(conn->pool);
3612 +#endif /* EAPI */
3613 +
3614 +#ifdef EAPI
3615 +    /*
3616 +     * Invoke the `new_connection' hook of modules to let them do
3617 +     * some connection dependent actions before we go on with
3618 +     * processing the request on this connection.
3619 +     */
3620 +    {
3621 +        module *m;
3622 +        for (m = top_module; m != NULL; m = m->next)
3623 +            if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
3624 +                if (m->new_connection != NULL)
3625 +                    (*m->new_connection)(conn);
3626 +    }
3627 +#endif /* EAPI */
3628  
3629      return conn;
3630  }
3631 @@ -3645,6 +3710,15 @@
3632      printf("Server's Module Magic Number: %u:%u\n",
3633            MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
3634      printf("Server compiled with....\n");
3635 +#ifdef EAPI
3636 +    printf(" -D EAPI\n");
3637 +#endif
3638 +#ifdef EAPI_MM
3639 +    printf(" -D EAPI_MM\n");
3640 +#ifdef EAPI_MM_CORE_PATH
3641 +    printf(" -D EAPI_MM_CORE_PATH=\"" EAPI_MM_CORE_PATH "\"\n");
3642 +#endif
3643 +#endif
3644  #ifdef BIG_SECURITY_HOLE
3645      printf(" -D BIG_SECURITY_HOLE\n");
3646  #endif
3647 @@ -3798,6 +3872,22 @@
3648      ap_server_pre_read_config  = ap_make_array(pcommands, 1, sizeof(char *));
3649      ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
3650      ap_server_config_defines   = ap_make_array(pcommands, 1, sizeof(char *));
3651 +
3652 +#ifdef EAPI
3653 +    ap_hook_init();
3654 +    ap_hook_configure("ap::buff::read", 
3655 +                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
3656 +    ap_hook_configure("ap::buff::write",  
3657 +                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
3658 +    ap_hook_configure("ap::buff::writev",  
3659 +                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
3660 +    ap_hook_configure("ap::buff::sendwithtimeout", 
3661 +                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
3662 +    ap_hook_configure("ap::buff::recvwithtimeout", 
3663 +                      AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
3664 +
3665 +    ap_global_ctx = ap_ctx_new(NULL);
3666 +#endif /* EAPI */
3667  }
3668  
3669  #ifndef MULTITHREAD
3670 @@ -4217,6 +4307,9 @@
3671  
3672             ap_sync_scoreboard_image();
3673             if (ap_scoreboard_image->global.running_generation != ap_my_generation) {
3674 +#ifdef EAPI
3675 +               ap_call_close_connection_hook(current_conn);
3676 +#endif /* EAPI */
3677                 ap_bclose(conn_io);
3678                 clean_child_exit(0);
3679             }
3680 @@ -4245,6 +4338,9 @@
3681          */
3682  
3683  #ifdef NO_LINGCLOSE
3684 +#ifdef EAPI
3685 +       ap_call_close_connection_hook(current_conn);
3686 +#endif /* EAPI */
3687         ap_bclose(conn_io);     /* just close it */
3688  #else
3689         if (r && r->connection
3690 @@ -4255,6 +4351,9 @@
3691             lingering_close(r);
3692         }
3693         else {
3694 +#ifdef EAPI
3695 +           ap_call_close_connection_hook(current_conn);
3696 +#endif /* EAPI */
3697             ap_bsetflag(conn_io, B_EOUT, 1);
3698             ap_bclose(conn_io);
3699         }
3700 @@ -4979,16 +5078,31 @@
3701             usage(argv[0]);
3702         }
3703      }
3704 +#ifdef EAPI
3705 +    ap_init_alloc_shared(TRUE);
3706 +#endif
3707  
3708      ap_suexec_enabled = init_suexec();
3709      server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
3710  
3711 +#ifdef EAPI
3712 +    ap_init_alloc_shared(FALSE);
3713 +#endif
3714 +
3715      if (ap_configtestonly) {
3716          fprintf(stderr, "Syntax OK\n");
3717 +#ifdef EAPI
3718 +        clean_parent_exit(0);
3719 +#else
3720          exit(0);
3721 +#endif
3722      }
3723      if (ap_dump_settings) {
3724 +#ifdef EAPI
3725 +        clean_parent_exit(0);
3726 +#else
3727          exit(0);
3728 +#endif
3729      }
3730  
3731      child_timeouts = !ap_standalone || one_process;
3732 @@ -5122,6 +5236,10 @@
3733             ap_destroy_pool(r->pool);
3734         }
3735  
3736 +#ifdef EAPI
3737 +       ap_call_close_connection_hook(conn);
3738 +#endif /* EAPI */
3739 +
3740         ap_bclose(cio);
3741      }
3742      exit(0);
3743 @@ -5468,6 +5586,9 @@
3744         ap_kill_cleanups_for_socket(ptrans, csd);
3745  
3746  #ifdef NO_LINGCLOSE
3747 +#ifdef EAPI
3748 +       ap_call_close_connection_hook(current_conn);
3749 +#endif /* EAPI */
3750         ap_bclose(conn_io);     /* just close it */
3751  #else
3752         if (r && r->connection
3753 @@ -5478,6 +5599,9 @@
3754             lingering_close(r);
3755         }
3756         else {
3757 +#ifdef EAPI
3758 +           ap_call_close_connection_hook(current_conn);
3759 +#endif /* EAPI */
3760             ap_bsetflag(conn_io, B_EOUT, 1);
3761             ap_bclose(conn_io);
3762         }
3763 @@ -6878,6 +7002,9 @@
3764          }
3765      }
3766  
3767 +#ifdef EAPI
3768 +    ap_init_alloc_shared(TRUE);
3769 +#endif
3770  
3771      if (!ap_os_is_path_absolute(ap_server_confname)) {
3772          char *full_conf_path;
3773 @@ -6929,6 +7056,10 @@
3774      }
3775  #else /* ndef WIN32 */
3776      server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
3777 +#endif
3778 +
3779 +#ifdef EAPI
3780 +    ap_init_alloc_shared(FALSE);
3781  #endif
3782  
3783      if (ap_configtestonly) {
3784 diff -urN apache_1.3.14.orig/src/main/http_protocol.c apache_1.3.14/src/main/http_protocol.c
3785 --- apache_1.3.14.orig/src/main/http_protocol.c Tue Oct 10 05:29:08 2000
3786 +++ apache_1.3.14/src/main/http_protocol.c      Sat Nov 11 20:49:14 2000
3787 @@ -1039,6 +1039,10 @@
3788      r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
3789      r->the_request     = NULL;
3790  
3791 +#ifdef EAPI
3792 +    r->ctx = ap_ctx_new(r->pool);
3793 +#endif /* EAPI */
3794 +
3795  #ifdef CHARSET_EBCDIC
3796      ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
3797  #endif
3798 @@ -1185,6 +1189,11 @@
3799      rnew->read_body       = REQUEST_NO_BODY;
3800  
3801      rnew->main = (request_rec *) r;
3802 +
3803 +#ifdef EAPI
3804 +    rnew->ctx = r->ctx;
3805 +#endif /* EAPI */
3806 +
3807  }
3808  
3809  void ap_finalize_sub_req_protocol(request_rec *sub)
3810 diff -urN apache_1.3.14.orig/src/main/http_request.c apache_1.3.14/src/main/http_request.c
3811 --- apache_1.3.14.orig/src/main/http_request.c  Fri Sep 22 20:42:42 2000
3812 +++ apache_1.3.14/src/main/http_request.c       Sat Nov 11 20:49:14 2000
3813 @@ -1383,6 +1383,9 @@
3814      new->no_local_copy   = r->no_local_copy;
3815      new->read_length     = r->read_length;     /* We can only read it once */
3816      new->vlist_validator = r->vlist_validator;
3817 +#ifdef EAPI
3818 +    new->ctx             = r->ctx;
3819 +#endif /* EAPI */
3820  
3821      ap_table_setn(new->subprocess_env, "REDIRECT_STATUS",
3822         ap_psprintf(r->pool, "%d", r->status));
3823 diff -urN apache_1.3.14.orig/src/modules/extra/mod_define.c apache_1.3.14/src/modules/extra/mod_define.c
3824 --- apache_1.3.14.orig/src/modules/extra/mod_define.c   Thu Jan  1 01:00:00 1970
3825 +++ apache_1.3.14/src/modules/extra/mod_define.c        Sat Nov 11 20:49:14 2000
3826 @@ -0,0 +1,416 @@
3827 +/*
3828 +**  mod_define.c - Apache module for configuration defines ($xxx)
3829 +**
3830 +**  Copyright (c) 1998-2000 Ralf S. Engelschall <rse@engelschall.com>
3831 +**  Copyright (c) 1998-2000 Christian Reiber <chrei@en.muc.de>
3832 +**
3833 +**  Permission to use, copy, modify, and distribute this software for
3834 +**  any purpose with or without fee is hereby granted, provided that
3835 +**  the above copyright notice and this permission notice appear in all
3836 +**  copies.
3837 +**
3838 +**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
3839 +**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3840 +**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3841 +**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
3842 +**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3843 +**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3844 +**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3845 +**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3846 +**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3847 +**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3848 +**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3849 +**  SUCH DAMAGE.
3850 +*/
3851 +
3852 +/*
3853 + *  HISTORY
3854 + *
3855 + *  v1.0: Originally written in December 1998 by
3856 + *        Ralf S. Engelschall <rse@engelschall.com> and
3857 + *        Christian Reiber <chrei@en.muc.de>
3858 + *
3859 + *  v1.1: Completely Overhauled in August 1999 by
3860 + *        Ralf S. Engelschall <rse@engelschall.com>
3861 + */
3862 +
3863 +#include "ap_config.h"
3864 +#include "ap_ctype.h"
3865 +#include "httpd.h"
3866 +#include "http_config.h"
3867 +#include "http_conf_globals.h"
3868 +#include "http_core.h"
3869 +#include "http_log.h"
3870 +
3871 +#ifndef EAPI
3872 +#error "This module requires the Extended API (EAPI) facilities."
3873 +#endif
3874 +
3875 +/*
3876 + * The global table of defines
3877 + */
3878 +
3879 +static table *tDefines         = NULL;   /* global table of defines */
3880 +static int    bOnceSeenADefine = FALSE;  /* optimization flag */
3881 +
3882 +/*
3883 + * Forward declaration
3884 + */
3885 +static int   DefineIndex      (pool *, char *, int *, int *, char **);
3886 +static char *DefineFetch      (pool *, char *);
3887 +static char *DefineExpand     (pool *, char *, int, char *);
3888 +static void  DefineInit       (pool *);
3889 +static void  DefineCleanup    (void *);
3890 +static char *DefineRewriteHook(cmd_parms *, void *, const char *);
3891 +
3892 +/*
3893 + * Character classes for scanner function
3894 + */
3895 +typedef enum {
3896 +    CC_ESCAPE, CC_DOLLAR, CC_BRACEOPEN, CC_BRACECLOSE,
3897 +    CC_IDCHAR1, CC_IDCHAR, CC_OTHER, CC_EOS
3898 +} CharClass;
3899 +
3900 +/*
3901 + * Scanner states for scanner function
3902 + */
3903 +typedef enum {
3904 +    SS_NONE, SS_SKIP, SS_DOLLAR, SS_TOKEN_BRACED,
3905 +    SS_TOKEN_UNBRACED, SS_ERROR, SS_FOUND
3906 +} ScanState;
3907 +
3908 +/*
3909 + * Default meta characters
3910 + */
3911 +#define DEFAULT_MC_ESCAPE      "\\"
3912 +#define DEFAULT_MC_DOLLAR      "$"
3913 +#define DEFAULT_MC_BRACEOPEN   "{"
3914 +#define DEFAULT_MC_BRACECLOSE  "}"
3915 +
3916 +/*
3917 + * Scanner for variable constructs $xxx and ${xxx}
3918 + */
3919 +static int DefineIndex(pool *p, char *cpLine, int *pos, int *len, char **cpVar)
3920 +{
3921 +    int rc;
3922 +    char *cp;
3923 +    char *cp2;
3924 +    CharClass cc;
3925 +    char cEscape;
3926 +    char cDefine;
3927 +    char cBraceOpen;
3928 +    char cBraceClose;
3929 +    char *cpError;
3930 +    ScanState s;
3931 +
3932 +    cEscape = DEFAULT_MC_ESCAPE[0];
3933 +    if ((cp = DefineFetch(p, "mod_define::escape")) != NULL)
3934 +        cEscape = cp[0];
3935 +    cDefine = DEFAULT_MC_DOLLAR[0];
3936 +    if ((cp = DefineFetch(p, "mod_define::dollar")) != NULL)
3937 +        cDefine = cp[0];
3938 +    cBraceOpen = DEFAULT_MC_BRACEOPEN[0];
3939 +    if ((cp = DefineFetch(p, "mod_define::braceopen")) != NULL)
3940 +        cBraceOpen = cp[0];
3941 +    cBraceClose = DEFAULT_MC_BRACECLOSE[0];
3942 +    if ((cp = DefineFetch(p, "mod_define::braceclose")) != NULL)
3943 +        cBraceClose = cp[0];
3944 +
3945 +    rc = 0;
3946 +    *len = 0;
3947 +    cc = CC_OTHER;
3948 +    s = SS_NONE;
3949 +    for (cp = cpLine+(*pos); cc != CC_EOS; cp++) {
3950 +        if (*cp == cEscape)
3951 +            cc = CC_ESCAPE;
3952 +        else if (*cp == cDefine)
3953 +            cc = CC_DOLLAR;
3954 +        else if (*cp == cBraceOpen)
3955 +            cc = CC_BRACEOPEN;
3956 +        else if (*cp == cBraceClose)
3957 +            cc = CC_BRACECLOSE;
3958 +        else if (ap_isalpha(*cp))
3959 +            cc = CC_IDCHAR1;
3960 +        else if (ap_isdigit(*cp) || *cp == '_' || *cp == ':')
3961 +            cc = CC_IDCHAR;
3962 +        else if (*cp == '\0')
3963 +            cc = CC_EOS;
3964 +        else
3965 +            cc = CC_OTHER;
3966 +        switch (s) {
3967 +            case SS_NONE:
3968 +                switch (cc) {
3969 +                    case CC_ESCAPE:
3970 +                        s = SS_SKIP;
3971 +                        break;
3972 +                    case CC_DOLLAR:
3973 +                        s = SS_DOLLAR;
3974 +                        break;
3975 +                    default:
3976 +                        break;
3977 +                }
3978 +                break;
3979 +            case SS_SKIP:
3980 +                s = SS_NONE;
3981 +                continue;
3982 +                break;
3983 +            case SS_DOLLAR:
3984 +                switch (cc) {
3985 +                    case CC_BRACEOPEN:
3986 +                        s = SS_TOKEN_BRACED;
3987 +                        *pos = cp-cpLine-1;
3988 +                        (*len) = 2;
3989 +                        *cpVar = cp+1;
3990 +                        break;
3991 +                    case CC_IDCHAR1:
3992 +                        s = SS_TOKEN_UNBRACED;
3993 +                        *pos = cp-cpLine-1;
3994 +                        (*len) = 2;
3995 +                        *cpVar = cp;
3996 +                        break;
3997 +                    case CC_ESCAPE:
3998 +                        s = SS_SKIP;
3999 +                        break;
4000 +                    default:
4001 +                        s = SS_NONE;
4002 +                        break;
4003 +                }
4004 +                break;
4005 +            case SS_TOKEN_BRACED:
4006 +                switch (cc) {
4007 +                    case CC_IDCHAR1:
4008 +                    case CC_IDCHAR:
4009 +                        (*len)++;
4010 +                        break;
4011 +                    case CC_BRACECLOSE:
4012 +                        (*len)++;
4013 +                        cp2 = ap_palloc(p, cp-*cpVar+1);
4014 +                        ap_cpystrn(cp2, *cpVar, cp-*cpVar+1);
4015 +                        *cpVar = cp2;
4016 +                        s = SS_FOUND;
4017 +                        break;
4018 +                    default:
4019 +                        cpError = ap_psprintf(p, "Illegal character '%c' in identifier", *cp);
4020 +                        s = SS_ERROR;
4021 +                        break;
4022 +                }
4023 +                break;
4024 +            case SS_TOKEN_UNBRACED:
4025 +                switch (cc) {
4026 +                    case CC_IDCHAR1:
4027 +                    case CC_IDCHAR:
4028 +                        (*len)++;
4029 +                        break;
4030 +                    default:
4031 +                        cp2 = ap_palloc(p, cp-*cpVar+1);
4032 +                        ap_cpystrn(cp2, *cpVar, cp-*cpVar+1);
4033 +                        *cpVar = cp2;
4034 +                        s = SS_FOUND;
4035 +                        break;
4036 +                }
4037 +                break;
4038 +            case SS_FOUND:
4039 +            case SS_ERROR:
4040 +                break;
4041 +        }
4042 +        if (s == SS_ERROR) {
4043 +            fprintf(stderr, "Error\n");
4044 +            break;
4045 +        }
4046 +        else if (s == SS_FOUND) {
4047 +            rc = 1;
4048 +            break;
4049 +        }
4050 +    }
4051 +    return rc;
4052 +}
4053 +
4054 +/*
4055 + * Determine the value of a variable
4056 + */
4057 +static char *DefineFetch(pool *p, char *cpVar)
4058 +{
4059 +    char *cpVal;
4060 +
4061 +    /* first try out table */
4062 +    if ((cpVal = (char *)ap_table_get(tDefines, (char *)cpVar)) != NULL)
4063 +        return cpVal;
4064 +    /* second try the environment */
4065 +    if ((cpVal = getenv(cpVar)) != NULL)
4066 +        return cpVal;
4067 +    return NULL;
4068 +}
4069 +
4070 +/*
4071 + * Expand a variable
4072 + */
4073 +static char *DefineExpand(pool *p, char *cpToken, int tok_len, char *cpVal)
4074 +{
4075 +    char *cp;
4076 +    int val_len, rest_len;
4077 +
4078 +    val_len  = strlen(cpVal);
4079 +    rest_len = strlen(cpToken+tok_len);
4080 +    if (val_len < tok_len)
4081 +        memcpy(cpToken+val_len, cpToken+tok_len, rest_len+1);
4082 +    else if (val_len > tok_len)
4083 +        for (cp = cpToken+strlen(cpToken); cp > cpToken+tok_len-1; cp--)
4084 +            *(cp+(val_len-tok_len)) = *cp;
4085 +    memcpy(cpToken, cpVal, val_len);
4086 +    return NULL;
4087 +}
4088 +
4089 +/*
4090 + * The EAPI hook which is called after Apache has read a
4091 + * configuration line and before it's actually processed
4092 + */
4093 +static char *DefineRewriteHook(cmd_parms *cmd, void *config, const char *line)
4094 +{
4095 +    pool *p;
4096 +    char *cpBuf;
4097 +    char *cpLine;
4098 +    int pos;
4099 +    int len;
4100 +    char *cpError;
4101 +    char *cpVar;
4102 +    char *cpVal;
4103 +    server_rec *s;
4104 +
4105 +    /* runtime optimization */
4106 +    if (!bOnceSeenADefine)
4107 +        return NULL;
4108 +
4109 +    p  = cmd->pool;
4110 +    s  = cmd->server;
4111 +
4112 +    /*
4113 +     * Search for:
4114 +     *  ....\$[a-zA-Z][:_a-zA-Z0-9]*....
4115 +     *  ....\${[a-zA-Z][:_a-zA-Z0-9]*}....
4116 +     */
4117 +    cpBuf = NULL;
4118 +    cpLine = (char *)line;
4119 +    pos = 0;
4120 +    while (DefineIndex(p, cpLine, &pos, &len, &cpVar)) {
4121 +#ifdef DEFINE_DEBUG
4122 +        {
4123 +        char prefix[1024];
4124 +        char marker[1024];
4125 +        int i;
4126 +        for (i = 0; i < pos; i++)
4127 +            prefix[i] = ' ';
4128 +        prefix[i] = '\0';
4129 +        for (i = 0; i < len; i++)
4130 +            marker[i] = '^';
4131 +        marker[i] = '\0';
4132 +        fprintf(stderr,
4133 +                "Found variable `%s' (pos: %d, len: %d)\n"
4134 +                "  %s\n"
4135 +                "  %s%s\n",
4136 +                cpVar, pos, len, cpLine, prefix, marker);
4137 +        }
4138 +#endif
4139 +        if (cpBuf == NULL) {
4140 +            cpBuf = ap_palloc(p, MAX_STRING_LEN);
4141 +            ap_cpystrn(cpBuf, line, MAX_STRING_LEN);
4142 +            cpLine = cpBuf;
4143 +        }
4144 +        if ((cpVal = DefineFetch(p, cpVar)) == NULL) {
4145 +            ap_log_error(APLOG_MARK, APLOG_ERR, s,
4146 +                         "mod_define: Variable '%s' not defined: file %s, line %d",
4147 +                         cpVar, cmd->config_file->name,
4148 +                         cmd->config_file->line_number);
4149 +            cpBuf = NULL;
4150 +            break;
4151 +        }
4152 +        if ((cpError = DefineExpand(p, cpLine+pos, len, cpVal)) != NULL) {
4153 +            ap_log_error(APLOG_MARK, APLOG_ERR, s,
4154 +                         "mod_define: %s: file %s, line %d",
4155 +                         cpError, cmd->config_file->name,
4156 +                         cmd->config_file->line_number);
4157 +            cpBuf = NULL;
4158 +            break;
4159 +        }
4160 +    }
4161 +    return cpBuf;
4162 +}
4163 +
4164 +/*
4165 + * Implementation of the `Define' configuration directive
4166 + */
4167 +static const char *cmd_define(cmd_parms *cmd, void *config,
4168 +                              char *cpVar, char *cpVal)
4169 +{
4170 +    if (tDefines == NULL)
4171 +        DefineInit(cmd->pool);
4172 +    ap_table_set(tDefines, cpVar, cpVal);
4173 +    bOnceSeenADefine = TRUE;
4174 +    return NULL;
4175 +}
4176 +
4177 +/*
4178 + * Module Initialization
4179 + */
4180 +
4181 +static void DefineInit(pool *p)
4182 +{
4183 +    tDefines = ap_make_table(p, 10);
4184 +    /* predefine delimiters */
4185 +    ap_table_set(tDefines, "mod_define::escape", DEFAULT_MC_ESCAPE);
4186 +    ap_table_set(tDefines, "mod_define::dollar", DEFAULT_MC_DOLLAR);
4187 +    ap_table_set(tDefines, "mod_define::open",   DEFAULT_MC_BRACEOPEN);
4188 +    ap_table_set(tDefines, "mod_define::close",  DEFAULT_MC_BRACECLOSE);
4189 +    ap_register_cleanup(p, NULL, DefineCleanup, ap_null_cleanup);
4190 +    return;
4191 +}
4192 +
4193 +/*
4194 + * Module Cleanup
4195 + */
4196 +
4197 +static void DefineCleanup(void *data)
4198 +{
4199 +    /* reset private variables when config pool is cleared */
4200 +    tDefines         = NULL;
4201 +    bOnceSeenADefine = FALSE;
4202 +    return;
4203 +}
4204 +
4205 +/*
4206 + * Module Directive lists
4207 + */
4208 +static const command_rec DefineDirectives[] = {
4209 +    { "Define", cmd_define, NULL, RSRC_CONF|ACCESS_CONF, TAKE2,
4210 +      "Define a configuration variable" },
4211 +    { NULL }
4212 +};
4213 +
4214 +/*
4215 + * Module API dispatch list
4216 + */
4217 +module MODULE_VAR_EXPORT define_module = {
4218 +    STANDARD_MODULE_STUFF,
4219 +    NULL,                  /* module initializer                  */
4220 +    NULL,                  /* create per-dir    config structures */
4221 +    NULL,                  /* merge  per-dir    config structures */
4222 +    NULL,                  /* create per-server config structures */
4223 +    NULL,                  /* merge  per-server config structures */
4224 +    DefineDirectives,      /* table of config file commands       */
4225 +    NULL,                  /* [#8] MIME-typed-dispatched handlers */
4226 +    NULL,                  /* [#1] URI to filename translation    */
4227 +    NULL,                  /* [#4] validate user id from request  */
4228 +    NULL,                  /* [#5] check if the user is ok _here_ */
4229 +    NULL,                  /* [#2] check access by host address   */
4230 +    NULL,                  /* [#6] determine MIME type            */
4231 +    NULL,                  /* [#7] pre-run fixups                 */
4232 +    NULL,                  /* [#9] log a transaction              */
4233 +    NULL,                  /* [#3] header parser                  */
4234 +    NULL,                  /* child_init                          */
4235 +    NULL,                  /* child_exit                          */
4236 +    NULL,                  /* [#0] post read-request              */
4237 +    NULL,                  /* EAPI: add_module                    */
4238 +    NULL,                  /* EAPI: del_module                    */
4239 +    DefineRewriteHook,     /* EAPI: rewrite_command               */
4240 +    NULL                   /* EAPI: new_connection                */
4241 +};
4242 +
4243 diff -urN apache_1.3.14.orig/src/modules/proxy/mod_proxy.c apache_1.3.14/src/modules/proxy/mod_proxy.c
4244 --- apache_1.3.14.orig/src/modules/proxy/mod_proxy.c    Fri Jun  2 01:42:26 2000
4245 +++ apache_1.3.14/src/modules/proxy/mod_proxy.c Sat Nov 11 20:49:14 2000
4246 @@ -214,6 +214,9 @@
4247  static int proxy_fixup(request_rec *r)
4248  {
4249      char *url, *p;
4250 +#ifdef EAPI
4251 +    int rc;
4252 +#endif /* EAPI */
4253  
4254      if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0)
4255         return DECLINED;
4256 @@ -221,6 +224,14 @@
4257      url = &r->filename[6];
4258  
4259  /* canonicalise each specific scheme */
4260 +#ifdef EAPI
4261 +    if (ap_hook_use("ap::mod_proxy::canon",
4262 +                    AP_HOOK_SIG3(int,ptr,ptr),
4263 +                    AP_HOOK_DECLINE(DECLINED),
4264 +                    &rc, r, url) && rc != DECLINED)
4265 +        return rc;  
4266 +    else
4267 +#endif /* EAPI */
4268      if (strncasecmp(url, "http:", 5) == 0)
4269         return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
4270      else if (strncasecmp(url, "ftp:", 4) == 0)
4271 @@ -236,9 +247,44 @@
4272  static void proxy_init(server_rec *r, pool *p)
4273  {
4274      ap_proxy_garbage_init(r, p);
4275 +#ifdef EAPI
4276 +    ap_hook_use("ap::mod_proxy::init", 
4277 +                AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p);
4278 +#endif
4279  }
4280  
4281 -
4282 +#ifdef EAPI
4283 +static void proxy_addmod(module *m)
4284 +{
4285 +    /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */
4286 +    ap_hook_configure("ap::mod_proxy::http::canon", 
4287 +                      AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
4288 +    ap_hook_register("ap::mod_proxy::http::canon", 
4289 +                     ap_proxy_http_canon, AP_HOOK_NOCTX);
4290 +
4291 +    /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */
4292 +    ap_hook_configure("ap::mod_proxy::http::handler", 
4293 +                      AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
4294 +    ap_hook_register("ap::mod_proxy::http::handler", 
4295 +                     ap_proxy_http_handler, AP_HOOK_NOCTX);
4296 +
4297 +    /* export: ap_proxyerror() as `ap::mod_proxy::error' */
4298 +    ap_hook_configure("ap::mod_proxy::error", 
4299 +                      AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST);
4300 +    ap_hook_register("ap::mod_proxy::error", 
4301 +                     ap_proxyerror, AP_HOOK_NOCTX);
4302 +    return;
4303 +}
4304 +
4305 +static void proxy_remmod(module *m)
4306 +{
4307 +       /* remove the hook references */
4308 +    ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon);
4309 +    ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler);
4310 +    ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror);
4311 +    return;
4312 +}
4313 +#endif /* EAPI */
4314  
4315  /* Send a redirection if the request contains a hostname which is not */
4316  /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
4317 @@ -368,6 +414,14 @@
4318                 /* CONNECT is a special method that bypasses the normal
4319                  * proxy code.
4320                  */
4321 +#ifdef EAPI
4322 +               if (!ap_hook_use("ap::mod_proxy::handler",
4323 +                                AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
4324 +                                AP_HOOK_DECLINE(DECLINED),
4325 +                                &rc, r, cr, url, 
4326 +                                ents[i].hostname, ents[i].port, 
4327 +                                ents[i].protocol) || rc == DECLINED) {
4328 +#endif /* EAPI */
4329                 if (r->method_number == M_CONNECT)
4330                     rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
4331                                                ents[i].port);
4332 @@ -377,6 +431,9 @@
4333                                             ents[i].port);
4334                 else
4335                     rc = DECLINED;
4336 +#ifdef EAPI
4337 +               }
4338 +#endif /* EAPI */
4339  
4340                 /* an error or success */
4341                 if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
4342 @@ -390,6 +447,14 @@
4343   * give up??
4344   */
4345      /* handle the scheme */
4346 +#ifdef EAPI
4347 +    if (ap_hook_use("ap::mod_proxy::handler",
4348 +                   AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
4349 +                   AP_HOOK_DECLINE(DECLINED),
4350 +                   &rc, r, cr, url, 
4351 +                    NULL, 0, scheme) && rc != DECLINED)
4352 +        return rc;
4353 +#endif /* EAPI */
4354      if (r->method_number == M_CONNECT)
4355         return ap_proxy_connect_handler(r, cr, url, NULL, 0);
4356      if (strcasecmp(scheme, "http") == 0)
4357 @@ -954,6 +1019,12 @@
4358      NULL,                      /* child_init */
4359      NULL,                      /* child_exit */
4360      proxy_detect               /* post read-request */
4361 +#ifdef EAPI
4362 +   ,proxy_addmod,              /* EAPI: add_module */
4363 +    proxy_remmod,              /* EAPI: remove_module */
4364 +    NULL,                      /* EAPI: rewrite_command */
4365 +    NULL                       /* EAPI: new_connection  */
4366 +#endif
4367  };
4368  
4369  
4370 diff -urN apache_1.3.14.orig/src/modules/proxy/proxy_http.c apache_1.3.14/src/modules/proxy/proxy_http.c
4371 --- apache_1.3.14.orig/src/modules/proxy/proxy_http.c   Tue Feb 29 15:24:27 2000
4372 +++ apache_1.3.14/src/modules/proxy/proxy_http.c        Sat Nov 11 20:49:14 2000
4373 @@ -189,6 +189,9 @@
4374      const char *urlptr = NULL;
4375      const char *datestr;
4376      struct tbl_do_args tdo;
4377 +#ifdef EAPI
4378 +    char *peer;
4379 +#endif
4380  
4381      void *sconf = r->server->module_config;
4382      proxy_server_conf *conf =
4383 @@ -207,6 +210,12 @@
4384         return HTTP_BAD_REQUEST;
4385      urlptr += 3;
4386      destport = DEFAULT_HTTP_PORT;
4387 +#ifdef EAPI
4388 +    ap_hook_use("ap::mod_proxy::http::handler::set_destport", 
4389 +                AP_HOOK_SIG2(int,ptr), 
4390 +                AP_HOOK_TOPMOST,
4391 +                &destport, r);
4392 +#endif /* EAPI */
4393      strp = strchr(urlptr, '/');
4394      if (strp == NULL) {
4395         desthost = ap_pstrdup(p, urlptr);
4396 @@ -243,12 +252,18 @@
4397         err = ap_proxy_host2addr(proxyhost, &server_hp);
4398         if (err != NULL)
4399             return DECLINED;    /* try another */
4400 +#ifdef EAPI
4401 +       peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);  
4402 +#endif
4403      }
4404      else {
4405         server.sin_port = htons(destport);
4406         err = ap_proxy_host2addr(desthost, &server_hp);
4407         if (err != NULL)
4408             return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
4409 +#ifdef EAPI
4410 +       peer =  ap_psprintf(p, "%s:%u", desthost, destport);  
4411 +#endif
4412      }
4413  
4414      sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
4415 @@ -305,13 +320,41 @@
4416      f = ap_bcreate(p, B_RDWR | B_SOCKET);
4417      ap_bpushfd(f, sock, sock);
4418  
4419 +#ifdef EAPI
4420 +    {
4421 +        char *errmsg = NULL;
4422 +        ap_hook_use("ap::mod_proxy::http::handler::new_connection", 
4423 +                    AP_HOOK_SIG4(ptr,ptr,ptr,ptr), 
4424 +                    AP_HOOK_DECLINE(NULL),
4425 +                    &errmsg, r, f, peer);
4426 +        if (errmsg != NULL)
4427 +            return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg);
4428 +    }
4429 +#endif /* EAPI */
4430 +
4431      ap_hard_timeout("proxy send", r);
4432      ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
4433            NULL);
4434 +#ifdef EAPI
4435 +    {
4436 +       int rc = DECLINED;
4437 +       ap_hook_use("ap::mod_proxy::http::handler::write_host_header", 
4438 +                   AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr), 
4439 +                   AP_HOOK_DECLINE(DECLINED),
4440 +                   &rc, r, f, desthost, destport, destportstr);
4441 +        if (rc == DECLINED) {
4442 +           if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
4443 +               ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
4444 +           else
4445 +               ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
4446 +        }
4447 +    }
4448 +#else /* EAPI */
4449      if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
4450         ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
4451      else
4452         ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
4453 +#endif /* EAPI */
4454  
4455      if (conf->viaopt == via_block) {
4456         /* Block all outgoing Via: headers */
4457 diff -urN apache_1.3.14.orig/src/modules/standard/mod_log_config.c apache_1.3.14/src/modules/standard/mod_log_config.c
4458 --- apache_1.3.14.orig/src/modules/standard/mod_log_config.c    Fri Jun  2 01:42:28 2000
4459 +++ apache_1.3.14/src/modules/standard/mod_log_config.c Sat Nov 11 20:49:14 2000
4460 @@ -257,6 +257,9 @@
4461  typedef const char *(*item_key_func) (request_rec *, char *);
4462  
4463  typedef struct {
4464 +#ifdef EAPI
4465 +    char ch;
4466 +#endif
4467      item_key_func func;
4468      char *arg;
4469      int condition_sense;
4470 @@ -554,15 +557,36 @@
4471      }
4472  };
4473  
4474 +#ifdef EAPI
4475 +static struct log_item_list *find_log_func(pool *p, char k)
4476 +#else /* EAPI */
4477  static struct log_item_list *find_log_func(char k)
4478 +#endif /* EAPI */
4479  {
4480      int i;
4481 +#ifdef EAPI
4482 +    struct log_item_list *lil;
4483 +#endif /* EAPI */
4484  
4485      for (i = 0; log_item_keys[i].ch; ++i)
4486          if (k == log_item_keys[i].ch) {
4487              return &log_item_keys[i];
4488          }
4489  
4490 +#ifdef EAPI
4491 +    if (ap_hook_status(ap_psprintf(p, "ap::mod_log_config::log_%c", k)) 
4492 +        != AP_HOOK_STATE_NOTEXISTANT) {
4493 +        lil = (struct log_item_list *)
4494 +              ap_pcalloc(p, sizeof(struct log_item_list));
4495 +        if (lil == NULL)
4496 +            return NULL;
4497 +        lil->ch = k;
4498 +        lil->func = NULL;
4499 +        lil->want_orig_default = 0;
4500 +        return lil;
4501 +    }
4502 +#endif /* EAPI */
4503 +
4504      return NULL;
4505  }
4506  
4507 @@ -688,7 +712,11 @@
4508              break;
4509  
4510          default:
4511 +#ifdef EAPI
4512 +            l = find_log_func(p, *s++);
4513 +#else /* EAPI */
4514              l = find_log_func(*s++);
4515 +#endif /* EAPI */
4516              if (!l) {
4517                  char dummy[2];
4518  
4519 @@ -697,6 +725,9 @@
4520                  return ap_pstrcat(p, "Unrecognized LogFormat directive %",
4521                                 dummy, NULL);
4522              }
4523 +#ifdef EAPI
4524 +            it->ch = s[-1];
4525 +#endif
4526              it->func = l->func;
4527              if (it->want_orig == -1) {
4528                  it->want_orig = l->want_orig_default;
4529 @@ -758,6 +789,15 @@
4530  
4531      /* We do.  Do it... */
4532  
4533 +#ifdef EAPI
4534 +    if (item->func == NULL) {
4535 +        cp = NULL;
4536 +        ap_hook_use(ap_psprintf(r->pool, "ap::mod_log_config::log_%c", item->ch),
4537 +                    AP_HOOK_SIG3(ptr,ptr,ptr), AP_HOOK_DECLINE(NULL),
4538 +                    &cp, r, item->arg);
4539 +    }
4540 +    else
4541 +#endif
4542      cp = (*item->func) (item->want_orig ? orig : r, item->arg);
4543      return cp ? cp : "-";
4544  }
4545 diff -urN apache_1.3.14.orig/src/modules/standard/mod_rewrite.c apache_1.3.14/src/modules/standard/mod_rewrite.c
4546 --- apache_1.3.14.orig/src/modules/standard/mod_rewrite.c       Fri Sep 22 22:47:19 2000
4547 +++ apache_1.3.14/src/modules/standard/mod_rewrite.c    Sat Nov 11 20:49:14 2000
4548 @@ -3613,6 +3613,15 @@
4549      }
4550  #endif /* ndef WIN32 && NETWARE*/
4551  
4552 +#ifdef EAPI
4553 +    else {
4554 +        ap_hook_use("ap::mod_rewrite::lookup_variable",
4555 +                    AP_HOOK_SIG3(ptr,ptr,ptr), 
4556 +                    AP_HOOK_DECLINE(NULL),
4557 +                    &result, r, var);
4558 +    }
4559 +#endif
4560 +
4561      if (result == NULL) {
4562          return ap_pstrdup(r->pool, "");
4563      }
4564 diff -urN apache_1.3.14.orig/src/modules/standard/mod_so.c apache_1.3.14/src/modules/standard/mod_so.c
4565 --- apache_1.3.14.orig/src/modules/standard/mod_so.c    Tue May  4 13:21:14 1999
4566 +++ apache_1.3.14/src/modules/standard/mod_so.c Sat Nov 11 20:49:14 2000
4567 @@ -257,11 +257,24 @@
4568       * Make sure the found module structure is really a module structure
4569       * 
4570       */
4571 +#ifdef EAPI
4572 +    if (   modp->magic != MODULE_MAGIC_COOKIE_AP13 
4573 +        && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
4574 +#else
4575      if (modp->magic != MODULE_MAGIC_COOKIE) {
4576 +#endif
4577          return ap_pstrcat(cmd->pool, "API module structure `", modname,
4578                            "' in file ", szModuleFile, " is garbled -"
4579                            " perhaps this is not an Apache module DSO?", NULL);
4580      }
4581 +#ifdef EAPI
4582 +    if (modp->magic == MODULE_MAGIC_COOKIE_AP13) {
4583 +        ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, NULL,
4584 +                     "Loaded DSO %s uses plain Apache 1.3 API, "
4585 +                     "this module might crash under EAPI! "
4586 +                     "(please recompile it with -DEAPI)", filename);
4587 +    }
4588 +#endif
4589  
4590      /* 
4591       * Add this module to the Apache core structures
4592 diff -urN apache_1.3.14.orig/src/modules/standard/mod_status.c apache_1.3.14/src/modules/standard/mod_status.c
4593 --- apache_1.3.14.orig/src/modules/standard/mod_status.c        Fri Jun  2 01:42:29 2000
4594 +++ apache_1.3.14/src/modules/standard/mod_status.c     Sat Nov 11 20:49:14 2000
4595 @@ -475,12 +475,33 @@
4596             if (no_table_report)
4597                 ap_rputs("<p><hr><h2>Server Details</h2>\n\n", r);
4598             else
4599 +#ifndef NO_PRETTYPRINT
4600 +               ap_rputs("<p>\n\n<table bgcolor=\"#ffffff\" border=\"0\">"
4601 +                       "<tr bgcolor=000000>"
4602 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Srv</b></font></td>"
4603 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>PID</b></font></td>"
4604 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Acc</b></font></td>"
4605 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>M</b></font></td>"
4606 +#ifndef NO_TIMES
4607 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>CPU</b></font></td>"
4608 +#endif
4609 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>SS</b></font></td>"
4610 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Req</b></font></td>"
4611 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Conn</b></font></td>"
4612 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Child</b></font></td>"
4613 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Slot</b></font></td>"
4614 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Host</b></font></td>"
4615 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>VHost</b></font></td>"
4616 +                       "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Request</b></td>"
4617 +                       "</tr>\n", r);      
4618 +#else /* NO_PRETTYPRINT */
4619  #ifdef NO_TIMES
4620                 /* Allow for OS/2 not having CPU stats */
4621                 ap_rputs("<p>\n\n<table border=0><tr><th>Srv<th>PID<th>Acc<th>M\n<th>SS<th>Req<th>Conn<th>Child<th>Slot<th>Client<th>VHost<th>Request</tr>\n\n", r);
4622  #else
4623                 ap_rputs("<p>\n\n<table border=0><tr><th>Srv<th>PID<th>Acc<th>M<th>CPU\n<th>SS<th>Req<th>Conn<th>Child<th>Slot<th>Client<th>VHost<th>Request</tr>\n\n", r);
4624  #endif
4625 +#endif /* NO_PRETTYPRINT */
4626         }
4627  
4628         for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
4629 @@ -598,14 +619,19 @@
4630                                 vhost->server_hostname) : "(unavailable)");
4631                     }
4632                     else {              /* !no_table_report */
4633 +#ifndef NO_PRETTYPRINT
4634 +                       ap_rprintf(r,"<tr bgcolor=\"#ffffff\">");
4635 +#else
4636 +                       ap_rprintf(r,"<tr>");
4637 +#endif
4638                         if (score_record.status == SERVER_DEAD)
4639                             ap_rprintf(r,
4640 -                               "<tr><td><b>%d-%d</b><td>-<td>%d/%lu/%lu",
4641 +                               "<td><b>%d-%d</b><td>-<td>%d/%lu/%lu",
4642                                 i, (int) ps_record.generation,
4643                                 (int) conn_lres, my_lres, lres);
4644                         else
4645                             ap_rprintf(r,
4646 -                               "<tr><td><b>%d-%d</b><td>%d<td>%d/%lu/%lu",
4647 +                               "<td><b>%d-%d</b><td>%d<td>%d/%lu/%lu",
4648                                 i, (int) ps_record.generation,
4649                                 (int) ps_record.pid, (int) conn_lres,
4650                                 my_lres, lres);
4651 @@ -665,12 +691,23 @@
4652                             ap_rprintf(r,
4653                              "<td>?<td nowrap>?<td nowrap>..reading.. </tr>\n\n");
4654                         else
4655 +#ifndef NO_PRETTYPRINT
4656 +                           ap_rprintf(r,
4657 +                            "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
4658 +                            "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
4659 +                            "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
4660 +                            "</tr>\n\n",
4661 +                            score_record.client,
4662 +                            vhost ? vhost->server_hostname : "(unavailable)",
4663 +                            ap_escape_html(r->pool, score_record.request));
4664 +#else
4665                             ap_rprintf(r,
4666                              "<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
4667                              ap_escape_html(r->pool, score_record.client),
4668                              vhost ? ap_escape_html(r->pool, 
4669                                 vhost->server_hostname) : "(unavailable)",
4670                              ap_escape_html(r->pool, score_record.request));
4671 +#endif
4672                     }           /* no_table_report */
4673                 }                       /* !short_report */
4674             }                   /* if (<active child>) */
4675 @@ -708,6 +745,12 @@
4676  </table>\n", r);
4677  #endif
4678         }
4679 +
4680 +#ifdef EAPI
4681 +    ap_hook_use("ap::mod_status::display",
4682 +                AP_HOOK_SIG4(void,ptr,int,int), AP_HOOK_ALL,
4683 +                r, no_table_report, short_report);
4684 +#endif
4685  
4686      } else {
4687  
4688 diff -urN apache_1.3.14.orig/src/support/apxs.pl apache_1.3.14/src/support/apxs.pl
4689 --- apache_1.3.14.orig/src/support/apxs.pl      Sat Nov 11 20:44:14 2000
4690 +++ apache_1.3.14/src/support/apxs.pl   Sat Nov 11 20:49:14 2000
4691 @@ -651,5 +651,11 @@
4692      NULL,                  /* child_init                          */
4693      NULL,                  /* child_exit                          */
4694      NULL                   /* [#0] post read-request              */
4695 +#ifdef EAPI
4696 +   ,NULL,                  /* EAPI: add_module                    */
4697 +    NULL,                  /* EAPI: remove_module                 */
4698 +    NULL,                  /* EAPI: rewrite_command               */
4699 +    NULL                   /* EAPI: new_connection                */
4700 +#endif
4701  };
4702  
4703 diff -urN apache_1.3.14.orig/src/support/httpd.exp apache_1.3.14/src/support/httpd.exp
4704 --- apache_1.3.14.orig/src/support/httpd.exp    Tue Oct 10 20:05:25 2000
4705 +++ apache_1.3.14/src/support/httpd.exp Sat Nov 11 20:49:14 2000
4706 @@ -421,3 +421,59 @@
4707  XML_SetUnparsedEntityDeclHandler
4708  XML_SetUserData
4709  XML_UseParserAsHandlerArg
4710 +ap_add_config_define
4711 +ap_make_shared_sub_pool
4712 +ap_global_ctx
4713 +ap_ctx_new
4714 +ap_ctx_get
4715 +ap_ctx_set
4716 +ap_hook_init
4717 +ap_hook_kill
4718 +ap_hook_configure
4719 +ap_hook_register_I
4720 +ap_hook_unregister_I
4721 +ap_hook_status
4722 +ap_hook_use
4723 +ap_hook_call
4724 +ap_mm_useable
4725 +ap_MM_create
4726 +ap_MM_permission
4727 +ap_MM_destroy
4728 +ap_MM_lock
4729 +ap_MM_unlock
4730 +ap_MM_malloc
4731 +ap_MM_realloc
4732 +ap_MM_free
4733 +ap_MM_calloc
4734 +ap_MM_strdup
4735 +ap_MM_sizeof
4736 +ap_MM_maxsize
4737 +ap_MM_available
4738 +ap_MM_error
4739 +ap_mm_create
4740 +ap_mm_permission
4741 +ap_mm_destroy
4742 +ap_mm_lock
4743 +ap_mm_unlock
4744 +ap_mm_malloc
4745 +ap_mm_realloc
4746 +ap_mm_free
4747 +ap_mm_calloc
4748 +ap_mm_strdup
4749 +ap_mm_sizeof
4750 +ap_mm_maxsize
4751 +ap_mm_available
4752 +ap_mm_error
4753 +ap_mm_display_info
4754 +ap_mm_core_create
4755 +ap_mm_core_permission
4756 +ap_mm_core_delete
4757 +ap_mm_core_size
4758 +ap_mm_core_lock
4759 +ap_mm_core_unlock
4760 +ap_mm_core_maxsegsize
4761 +ap_mm_core_align2page
4762 +ap_mm_core_align2word
4763 +ap_mm_lib_error_set
4764 +ap_mm_lib_error_get
4765 +ap_mm_lib_version
This page took 0.387331 seconds and 2 git commands to generate.