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