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
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"><Directory></A>
11 <LI><A HREF="core.html#directorymatch"><DirectoryMatch></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
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
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
28 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
30 +<!-- mod_define.html -->
31 +<!-- Documentation for the mod_define Apache module -->
34 +<TITLE>Apache module mod_define</TITLE>
37 +<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
45 +<BLOCKQUOTE><!-- page indentation -->
46 +<!--#include virtual="header.html" -->
49 +<H1 ALIGN="CENTER">Module mod_define</H1>
50 +<H2 ALIGN="CENTER">Variable Definition For Arbitrary Directives</H2>
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>
61 + AddModule modules/extra/mod_define.o
67 +<H3><A NAME="Define">Define</A></H3>
69 + HREF="directive-dict.html#Syntax"
71 +><STRONG>Syntax:</STRONG></A>
72 + <CODE>Define</CODE> <EM>variable</EM> <EM>value</EM><BR>
74 + HREF="directive-dict.html#Default"
76 +><STRONG>Default:</STRONG></A>
79 + HREF="directive-dict.html#Context"
81 +><STRONG>Context:</STRONG></A>
82 + server config, virtual host, directory, .htaccess<BR>
84 + HREF="directive-dict.html#Override"
86 +><STRONG>Override:</STRONG></A> none<BR>
88 + HREF="directive-dict.html#Status"
90 +><STRONG>Status:</STRONG></A> Extension<BR>
92 + HREF="directive-dict.html#Module"
94 +><STRONG>Module:</STRONG></A> mod_define.c<BR>
96 + HREF="directive-dict.html#Compatibility"
98 +><STRONG>Compatibility:</STRONG></A> Apache+EAPI<BR>
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).
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:
124 +Define mod_define::escape "\\"
125 +Define mod_define::dollar "$"
126 +Define mod_define::open "{"
127 +Define mod_define::close "}"
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.
137 +<STRONG>Example:</STRONG>
140 +Define master "Joe Average <joe@average.dom>"
141 +Define docroot /usr/local/apache/htdocs
143 +Define domainname bar.dom
144 +Define portnumber 80
146 +<VirtualHost $hostname.$domainname:$portnumber>
147 +SetEnv SERVER_MASTER "$master"
148 +ServerName $hostname.$domainname
149 +ServerAlias $hostname
151 +DocumentRoot $docroot
152 +<Directory $docroot>
158 +<!--#include virtual="footer.html" -->
159 +</BLOCKQUOTE><!-- page indentation -->
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
169 ap_send_error_response @357
170 + ap_add_config_define @358
177 + ap_hook_configure @365
178 + ap_hook_register_I @366
179 + ap_hook_unregister_I @367
180 + ap_hook_status @368
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
190 ################################################################
191 +# Extended API (EAPI) support:
194 +# The EAPI rule enables more module hooks, a generic low-level hook
195 +# mechanism, a generic context mechanism and shared memory based pools.
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
208 +################################################################
209 # Dynamic Shared Object (DSO) support
211 # There is experimental support for compiling the Apache core and
213 ## it does not do per-request stuff.
215 AddModule modules/standard/mod_env.o
217 +## mod_define expands variables on arbitrary directive lines.
218 +## It requires Extended API (EAPI).
220 +# AddModule modules/extra/mod_define.o
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 @@
230 ####################################################################
231 +## Extended API (EAPI) support:
233 +if [ "x$RULE_EAPI" = "x" ]; then
234 + RULE_EAPI=`./helpers/CutRule EAPI $file`
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.
242 + *IRIX-32*:*/cc|*IRIX-32*:cc )
243 + CFLAGS="$CFLAGS -woff 1048,1110,1164"
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}'`
250 + if [ "x$EAPI_MM" != "x" ]; then
253 + * ) for p in . .. ../..; do
254 + if [ -d "$p/$EAPI_MM" ]; then
255 + EAPI_MM="`echo $p/$EAPI_MM | sed -e 's;/\./;/;g'`"
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"
268 + LDFLAGS="$LDFLAGS `mm-config --ldflags`"
269 + LIBS="$LIBS `mm-config --libs`"
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)"
275 + * ) EAPI_MM="\$(SRCDIR)/$EAPI_MM" ;;
277 + CFLAGS="$CFLAGS -DEAPI_MM"
278 + INCLUDES="$INCLUDES -I$EAPI_MM"
279 + LDFLAGS="$LDFLAGS -L$EAPI_MM/.libs"
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`"
288 + echo "Configure:Error: Cannot find MM library under $EAPI_MM" 1>&2
296 +####################################################################
297 ## Add in the Expat library if needed/wanted.
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
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
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
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"
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" \
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"
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
360 +/* ====================================================================
361 + * Copyright (c) 1998-2000 The Apache Group. All rights reserved.
363 + * Redistribution and use in source and binary forms, with or without
364 + * modification, are permitted provided that the following conditions
367 + * 1. Redistributions of source code must retain the above copyright
368 + * notice, this list of conditions and the following disclaimer.
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
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/)."
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.
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.
389 + * 6. Redistributions of any form whatsoever must retain the following
391 + * "This product includes software developed by the Apache Group
392 + * for use in the Apache HTTP server project (http://www.apache.org/)."
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 + * ====================================================================
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/>.
418 +** Generic Context Interface for Apache
419 +** Written by Ralf S. Engelschall <rse@engelschall.com>
425 +#include "ap_config.h"
428 +API_EXPORT(ap_ctx *) ap_ctx_new(pool *p)
434 + ctx = (ap_ctx *)ap_palloc(p, sizeof(ap_ctx_rec));
436 + ctx->cr_entry = (ap_ctx_entry **)
437 + ap_palloc(p, sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
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));
445 + for (i = 0; i < AP_CTX_MAX_ENTRIES+1; i++)
446 + ctx->cr_entry[i] = NULL;
450 +API_EXPORT(void) ap_ctx_set(ap_ctx *ctx, char *key, void *val)
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];
463 + if (i == AP_CTX_MAX_ENTRIES)
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);
470 + ce = (ap_ctx_entry *)malloc(sizeof(ap_ctx_entry));
471 + ce->ce_key = strdup(key);
473 + ctx->cr_entry[i] = ce;
474 + ctx->cr_entry[i+1] = NULL;
480 +API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key)
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;
490 +API_EXPORT(ap_ctx *) ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base)
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__);
505 + if ((new = ap_ctx_new(p)) == 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);
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
522 +/* ====================================================================
523 + * Copyright (c) 1998-2000 The Apache Group. All rights reserved.
525 + * Redistribution and use in source and binary forms, with or without
526 + * modification, are permitted provided that the following conditions
529 + * 1. Redistributions of source code must retain the above copyright
530 + * notice, this list of conditions and the following disclaimer.
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
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/)."
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.
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.
551 + * 6. Redistributions of any form whatsoever must retain the following
553 + * "This product includes software developed by the Apache Group
554 + * for use in the Apache HTTP server project (http://www.apache.org/)."
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 + * ====================================================================
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/>.
580 +** Implementation of a Generic Hook Interface for Apache
581 +** Written by Ralf S. Engelschall <rse@engelschall.com>
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''
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.
594 + * Premature optimization is
595 + * the root of all evil.
602 +#include "http_log.h"
603 +#include "ap_config.h"
604 +#include "ap_hook.h"
607 + * the internal hook pool
609 +static ap_hook_entry **ap_hook_pool = NULL;
612 + * forward prototypes for internal functions
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);
620 + * Initialize the hook mechanism
622 +API_EXPORT(void) ap_hook_init(void)
626 + if (ap_hook_pool != NULL)
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;
636 + * Kill the hook mechanism
638 +API_EXPORT(void) ap_hook_kill(void)
642 + if (ap_hook_pool == NULL)
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;
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)
655 +static ap_hook_entry *ap_hook_create(char *hook)
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];
664 + if (i >= AP_HOOK_MAX_ENTRIES)
667 + if ((he = (ap_hook_entry *)malloc(sizeof(ap_hook_entry))) == NULL)
669 + ap_hook_pool[i] = he;
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;
676 + he->he_func = (ap_hook_func **)malloc(sizeof(ap_hook_func *)
677 + *(AP_HOOK_MAX_FUNCS+1));
678 + if (he->he_func == NULL)
681 + for (i = 0; i < AP_HOOK_MAX_FUNCS; i++)
682 + he->he_func[i] = NULL;
687 + * Find a particular hook
689 +static ap_hook_entry *ap_hook_find(char *hook)
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];
700 + * Destroy a particular hook
702 +static void ap_hook_destroy(ap_hook_entry *he)
709 + for (i = 0; he->he_func[i] != NULL; i++)
710 + free(he->he_func[i]);
717 + * Configure a particular hook,
718 + * i.e. remember its signature and return value mode
720 +API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
726 + va_start(ap, modeid);
727 + if ((he = ap_hook_create(hook)) == NULL)
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));
753 + * Register a function to call for a hook
755 +API_EXPORT(int) ap_hook_register_I(char *hook, void *func, void *ctx)
761 + if ((he = ap_hook_create(hook)) == NULL)
764 + for (i = 0; he->he_func[i] != NULL; i++)
765 + if (he->he_func[i]->hf_ptr == func)
768 + if (i == AP_HOOK_MAX_FUNCS)
771 + if ((hf = (ap_hook_func *)malloc(sizeof(ap_hook_func))) == NULL)
774 + for (j = i; j >= 0; j--)
775 + he->he_func[j+1] = he->he_func[j];
776 + he->he_func[0] = hf;
785 + * Unregister a function to call for a hook
787 +API_EXPORT(int) ap_hook_unregister_I(char *hook, void *func)
792 + if ((he = ap_hook_find(hook)) == NULL)
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];
806 + * Retrieve the status of a particular hook
808 +API_EXPORT(ap_hook_state) ap_hook_status(char *hook)
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;
825 + * Use a hook, i.e. optional on-the-fly configure it before calling it
827 +API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
830 + ap_hook_value modeval;
835 + va_start(ap, modeid);
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));
852 + if ((he = ap_hook_create(hook)) == NULL)
855 + if (he->he_sig == AP_HOOK_SIG_UNKNOWN)
857 + if (he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
858 + he->he_modeid = modeid;
859 + he->he_modeval = modeval;
862 + for (i = 0; he->he_func[i] != NULL; i++)
863 + if (ap_hook_call_func(ap, he, he->he_func[i]))
866 + if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
868 + else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
880 +API_EXPORT(int) ap_hook_call(char *hook, ...)
887 + va_start(ap, hook);
889 + if ((he = ap_hook_find(hook)) == NULL) {
893 + if ( he->he_sig == AP_HOOK_SIG_UNKNOWN
894 + || he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
899 + for (i = 0; he->he_func[i] != NULL; i++)
900 + if (ap_hook_call_func(ap, he, he->he_func[i]))
903 + if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
905 + else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
914 +static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf)
917 + ap_hook_value v_tmp;
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):
928 + * 1. `The basic hook'.
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.
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)
967 + * 3. Actually currently used hooks.
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]
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
992 + * This automatically updates the above code.
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;
1014 + /* the return variable is provided by caller */
1015 + v_rc = va_arg(ap, void *);
1019 + /* ----BEGIN GENERATED SECTION-------- */
1020 + if (he->he_sig == AP_HOOK_SIG1(void)) {
1021 + /* Call: void func() */
1022 + ((void(*)())(hf->hf_ptr))();
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1325 + /* ----END GENERATED SECTION---------- */
1327 + ap_log_assert("hook signature not implemented", __FILE__, __LINE__);
1329 + if (he->he_modeid == AP_HOOK_MODE_ALL)
1331 + else if (he->he_modeid == AP_HOOK_MODE_TOPMOST)
1342 +## Embedded Perl script for generating the dispatch section
1350 +my $begin = '----BEGIN GENERATED SECTION--------';
1351 +my $end = '----END GENERATED SECTION----------';
1353 +# special command: find used signatures
1354 +if ($ARGV[0] eq 'used') {
1355 + my @S = `find .. -type f -name "*.c" -print`;
1360 + open(FP, "<$s") || die;
1362 + $source .= $_ while (<FP>);
1366 + my ($src, $hook, $sig) = @_;
1367 + return if ($seen{$hook} == 1);
1369 + my ($rc, $args) = ($sig =~ m|^([^,]+)(.*)$|);
1372 + my $sig = sprintf("%-6sfunc(%s)", $rc, $args);
1375 + $source =~ s|\("([^"]+)",\s*AP_HOOK_SIG[0-9]\((.+?)\)|&printme($s, $1, $2), ''|sge;
1378 + foreach $t (sort(keys(%T))) {
1379 + printf(" * %-40s [%dx]\n", $t, $T{$t});
1384 +# read ourself and keep a backup
1385 +open(FP, "<$file") || die;
1387 +$source .= $_ while (<FP>);
1389 +open(FP, ">$file.bak") || die;
1393 +# now parse the signature lines and update the code
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;
1403 + next if ($seen{$sig} == 1);
1406 + print "Generating code for `$sig'\n";
1408 + my @S = ($rc, split(/[\s,]+/, $param));
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');
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]);
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]));
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);
1432 + $o .= sprintf(" rc = (*((%s *)v_rc) != he->he_modeval.v_%s);\n",
1433 + $RS[0], $S[0]) if ($S[0] ne 'void');
1437 +# insert the generated code at the target location
1439 +$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s;
1441 +# and update the source on disk
1442 +print "Updating file `$file'\n";
1443 +open(FP, ">$file") || die;
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
1453 +/* ====================================================================
1454 + * Copyright (c) 1999-2000 The Apache Group. All rights reserved.
1456 + * Redistribution and use in source and binary forms, with or without
1457 + * modification, are permitted provided that the following conditions
1460 + * 1. Redistributions of source code must retain the above copyright
1461 + * notice, this list of conditions and the following disclaimer.
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
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/)."
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.
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.
1482 + * 6. Redistributions of any form whatsoever must retain the following
1484 + * "This product includes software developed by the Apache Group
1485 + * for use in the Apache HTTP server project (http://www.apache.org/)."
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 + * ====================================================================
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/>.
1510 +** ap_mm.c -- wrapper for MM shared memory library
1512 +** This file has two reason:
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.
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
1525 + * "What you see is all you get."
1526 + * -- Brian Kernighan
1535 +API_EXPORT(int) ap_mm_useable(void) { return TRUE; }
1536 +#define STUB(val,nul) { return val; }
1537 +#define STUB_STMT(stmt) { stmt; return; }
1539 +API_EXPORT(int) ap_mm_useable(void) { return FALSE; }
1540 +#define STUB(val,nul) { return nul; }
1541 +#define STUB_STMT(stmt) { return; }
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)
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))
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)
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)
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
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 */
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 *);
1647 API_EXPORT(void) ap_destroy_pool(pool *);
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
1654 +/* ====================================================================
1655 + * Copyright (c) 1998-2000 The Apache Group. All rights reserved.
1657 + * Redistribution and use in source and binary forms, with or without
1658 + * modification, are permitted provided that the following conditions
1661 + * 1. Redistributions of source code must retain the above copyright
1662 + * notice, this list of conditions and the following disclaimer.
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
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/)."
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.
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.
1683 + * 6. Redistributions of any form whatsoever must retain the following
1685 + * "This product includes software developed by the Apache Group
1686 + * for use in the Apache HTTP server project (http://www.apache.org/)."
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 + * ====================================================================
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/>.
1712 +** Generic Context Interface for Apache
1713 +** Written by Ralf S. Engelschall <rse@engelschall.com>
1723 +#define TRUE !FALSE
1727 + * Internal Context Record Definition
1730 +#define AP_CTX_MAX_ENTRIES 1024
1739 + ap_ctx_entry **cr_entry;
1742 +typedef ap_ctx_rec ap_ctx;
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
1749 +#define AP_CTX_NUM2PTR(n) (void *)((unsigned int)(n)+1)
1750 +#define AP_CTX_PTR2NUM(p) (unsigned int)(((char *)(p))-1)
1753 + * Prototypes for Context Handling Functions
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);
1761 +#endif /* AP_CTX_H */
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
1771 +/* ====================================================================
1772 + * Copyright (c) 1998-2000 The Apache Group. All rights reserved.
1774 + * Redistribution and use in source and binary forms, with or without
1775 + * modification, are permitted provided that the following conditions
1778 + * 1. Redistributions of source code must retain the above copyright
1779 + * notice, this list of conditions and the following disclaimer.
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
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/)."
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.
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.
1800 + * 6. Redistributions of any form whatsoever must retain the following
1802 + * "This product includes software developed by the Apache Group
1803 + * for use in the Apache HTTP server project (http://www.apache.org/)."
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 + * ====================================================================
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/>.
1829 +** Implementation of a Generic Hook Interface for Apache
1830 +** Written by Ralf S. Engelschall <rse@engelschall.com>
1832 +** See POD document at end of this file for description.
1833 +** View it with the command ``pod2man ap_hook.h | nroff -man | more''
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.
1848 + * Function Signature Specification:
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(...)
1855 +/* the type of the signature bitfield */
1856 +typedef unsigned long int ap_hook_sig;
1858 +/* the mask (bin) 111 (hex 0x7) for the triples in the bitfield */
1859 +#define AP_HOOK_SIG_TRIPLE_MASK 0x7
1861 +/* the position of the triple */
1862 +#define AP_HOOK_SIG_TRIPLE_POS(n) ((n)*3)
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))
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))
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))
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)))
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
1975 +/* the constructor for unknown signatures */
1976 +#define AP_HOOK_SIG_UNKNOWN AP_HOOK_ID_undef
1978 +/* the constructor for signatures with 1 type */
1979 +#define AP_HOOK_SIG1(rc) \
1982 +/* the constructor for signatures with 2 types */
1983 +#define AP_HOOK_SIG2(rc,a1) \
1984 + (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1)
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)
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)
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)
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)
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)
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)
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)
2015 + * Return Value Mode Identification
2018 +/* the type of the return value modes */
2019 +typedef unsigned int ap_hook_mode;
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
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
2035 + * Hook State Identification
2038 +/* the type of the hook state */
2039 +typedef unsigned short int ap_hook_state;
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
2049 + * Hook Context Identification
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.
2056 +#define AP_HOOK_NOCTX (void *)(0)
2057 +#define AP_HOOK_CTX(v) (void *)(v)
2060 + * Internal Hook Record Definition
2063 +/* the union holding the arbitrary decline values */
2073 +/* the structure holding one hook function and its context */
2075 + void *hf_ptr; /* function pointer */
2076 + void *hf_ctx; /* function context */
2079 +/* the structure holding one hook entry with all its registered functions */
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 */
2088 +/* the maximum number of hooks and functions per hook */
2089 +#define AP_HOOK_MAX_ENTRIES 512
2090 +#define AP_HOOK_MAX_FUNCS 128
2093 + * Extended Variable Argument (vararg) Support
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.
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 *
2113 +/* the constructor */
2117 +#define va_type(type) VA_TYPE_ ## type
2120 + * Miscellaneous stuff
2125 +#define TRUE !FALSE
2129 + * Wrapper macros for the callback-function register/unregister calls.
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.
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))
2143 + * Prototypes for the hook API functions
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, ...);
2155 +#endif /* AP_HOOK_H */
2161 +## Embedded POD document
2166 +B<ap_hook> - B<Generic Hook Interface for Apache>
2170 +B<Hook Library Setup:>
2172 + void ap_hook_init(void);
2173 + void ap_hook_kill(void);
2175 +B<Hook Configuration and Registration:>
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);
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, ...);
2187 +B<Hook Signature Constructors> (ap_hook_sig):
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)
2198 +B<Hook Modes Constructors> (ap_hook_mode):
2201 + AP_HOOK_DECLINE(value)
2202 + AP_HOOK_DECLTMP(value)
2205 +B<Hook States> (ap_hook_state):
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
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
2221 +=item B<1. Extension and Overrides>
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
2231 +The original intent of this use case is to provide a flexible extension
2232 +mechanism where modules can override functionality.
2234 +=item B<2. Intercommunication>
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.
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.
2247 +And the following design goals existed:
2251 +=item B<1. Minimum code changes>
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.
2260 +=item B<2. The hook call has to be maximum flexible>
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.
2270 +The implementation of this library directly followed these two design goals.
2274 +Using this hook API is a four-step process:
2278 +=item B<1. Initialization>
2280 +Initialize or destroy the hook mechanism inside your application program:
2286 +=item B<2. Configuration>
2288 +Configure a particular hook by specifing its name, signature and return type
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);
2296 +This configures four hooks:
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>.
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
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>.
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>.
2331 +=item B<3. Registration>
2333 +Register the actual functions which should be used by the hook:
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);
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>.
2347 +Finally use the hooks, i.e. instead of using direct function calls like
2349 + rc = mylookup(a1, a2);
2350 + rc = mysetup(a1, a2);
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);
2361 +which are internally translated to:
2363 + rc = mylookup(a1, a2, mycontext);
2364 + rc = mysetup(a1, a2);
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).
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.
2382 +=head1 RESTRICTIONS
2384 +To make the hook implementation efficient and to not bloat up the code too
2385 +much a few restrictions have to make:
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.
2399 +Only the following ANSI C variable types are supported:
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 *)
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>
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):
2422 + ssize_t my_read(int, void *, size_t);
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.
2431 + ap_hook_configure("read",
2432 + AP_HOOK_SIG4(int,int,ptr,int),
2433 + AP_HOOK_DECLINE(-1));
2434 + ap_hook_register("read", read);
2436 +Now a module wants to override the C<read()> call and registers the
2437 +C<my_read()> function:
2439 + ap_hook_register("read", my_read);
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
2445 + bytes = read(fd, buf, bufsize);
2449 +with the hook based call:
2451 + rc = ap_hook_call("read", &bytes, fd, buf, bufsize);
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'.
2467 +The ap_hook(3) interface was originally designed and
2468 +implemented in October 1998 by Ralf S. Engelschall.
2472 + Ralf S. Engelschall
2473 + rse@engelschall.com
2474 + www.engelschall.com
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
2482 +/* ====================================================================
2483 + * Copyright (c) 1999-2000 The Apache Group. All rights reserved.
2485 + * Redistribution and use in source and binary forms, with or without
2486 + * modification, are permitted provided that the following conditions
2489 + * 1. Redistributions of source code must retain the above copyright
2490 + * notice, this list of conditions and the following disclaimer.
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
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/)."
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.
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.
2511 + * 6. Redistributions of any form whatsoever must retain the following
2513 + * "This product includes software developed by the Apache Group
2514 + * for use in the Apache HTTP server project (http://www.apache.org/)."
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 + * ====================================================================
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/>.
2540 +** ap_mm.h -- wrapper code for MM shared memory library
2551 +#define TRUE !FALSE
2554 +API_EXPORT(int) ap_mm_useable(void);
2556 +typedef void AP_MM;
2557 +typedef enum { AP_MM_LOCK_RD, AP_MM_LOCK_RW } ap_mm_lock_mode;
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);
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);
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);
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);
2608 +#endif /* AP_MM_H */
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()
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").
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
2634 #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
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 */
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);
2659 +#define ap_bpeekc(fb) ( ((fb)->incnt == 0) ? EOF : *((fb)->inptr) )
2662 #ifndef CHARSET_EBCDIC
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
2668 extern int ap_listenbacklog;
2669 extern int ap_dump_settings;
2670 extern API_VAR_EXPORT int ap_extended_status;
2672 +extern API_VAR_EXPORT ap_ctx *ap_global_ctx;
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 *);
2683 int (*post_read_request) (request_rec *);
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:
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.
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.
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.
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.
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.
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) ();
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 *);
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);
2754 +API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x);
2756 unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x);
2758 API_EXPORT(int) ap_check_alarm(void);
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
2765 /* Headers in which EVERYONE has an interest... */
2767 #include "ap_config.h"
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.
2778 +#include "ap_hook.h"
2779 +#include "ap_ctx.h"
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))
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)
2792 #define ap_http_method(r) "http"
2793 #define ap_default_port(r) DEFAULT_HTTP_PORT
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
2804 + * Path to Shared Memory Files
2807 +#ifndef EAPI_MM_CORE_PATH
2808 +#define EAPI_MM_CORE_PATH "logs/mm"
2810 +#ifndef EAPI_MM_CORE_MAXSIZE
2811 +#define EAPI_MM_CORE_MAXSIZE 1024*1024*1 /* max. 1MB */
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.
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);
2823 +API_EXPORT(void) ap_add_config_define(const char *define);
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.
2840 char *local_host; /* used for ap_get_server_name when
2841 * UseCanonicalName is set to DNS
2842 * (ignores setting of HostnameLookups) */
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 */
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
2868 +#include "http_config.h"
2869 +#include "http_conf_globals.h"
2871 #include "multithread.h"
2872 #include "http_log.h"
2874 @@ -137,6 +141,10 @@
2875 #define BLOCK_MINALLOC 0
2878 +#if defined(EAPI) && defined(EAPI_MM)
2879 +static AP_MM *mm = NULL;
2882 /*****************************************************************
2884 * Managing free storage blocks...
2887 union block_hdr *next;
2889 +#if defined(EAPI) && defined(EAPI_MM)
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. */
2899 +#if defined(EAPI) && defined(EAPI_MM)
2900 +static union block_hdr *malloc_block(int size, int is_shm)
2902 static union block_hdr *malloc_block(int size)
2905 union block_hdr *blok;
2907 @@ -229,12 +244,20 @@
2909 num_malloc_bytes += size + sizeof(union block_hdr);
2911 +#if defined(EAPI) && defined(EAPI_MM)
2913 + blok = (union block_hdr *)ap_mm_malloc(mm, size + sizeof(union block_hdr));
2916 blok = (union block_hdr *) malloc(size + sizeof(union block_hdr));
2918 fprintf(stderr, "Ouch! malloc failed in malloc_block()\n");
2921 debug_fill(blok, size + sizeof(union block_hdr));
2922 +#if defined(EAPI) && defined(EAPI_MM)
2923 + blok->h.is_shm = is_shm;
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 @@
2930 return; /* Sanity check --- freeing empty pool? */
2932 +#if defined(EAPI) && defined(EAPI_MM)
2933 + if (blok->h.is_shm)
2934 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
2936 (void) ap_acquire_mutex(alloc_mutex);
2937 old_free_list = block_freelist;
2938 block_freelist = blok;
2939 @@ -341,6 +368,10 @@
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);
2950 @@ -349,7 +380,11 @@
2951 * if necessary. Must be called with alarms blocked.
2954 +#if defined(EAPI) && defined(EAPI_MM)
2955 +static union block_hdr *new_block(int min_size, int is_shm)
2957 static union block_hdr *new_block(int min_size)
2960 union block_hdr **lastptr = &block_freelist;
2961 union block_hdr *blok = block_freelist;
2962 @@ -359,7 +394,12 @@
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) {
2970 if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
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 @@
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);
2982 blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
2989 struct pool *joined;
2991 +#if defined(EAPI) && defined(EAPI_MM)
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)
3001 +#if defined(EAPI) && defined(EAPI_MM)
3002 +static struct pool *make_sub_pool_internal(struct pool *p, int is_shm)
3004 API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
3007 union block_hdr *blok;
3012 +#if defined(EAPI) && defined(EAPI_MM)
3014 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3016 (void) ap_acquire_mutex(alloc_mutex);
3018 +#if defined(EAPI) && defined(EAPI_MM)
3019 + blok = new_block(POOL_HDR_BYTES, is_shm);
3021 blok = new_block(POOL_HDR_BYTES);
3023 new_pool = (pool *) blok->h.first_avail;
3024 blok->h.first_avail += POOL_HDR_BYTES;
3026 @@ -467,12 +526,38 @@
3027 p->sub_pools = new_pool;
3030 +#if defined(EAPI) && defined(EAPI_MM)
3031 + new_pool->is_shm = is_shm;
3034 (void) ap_release_mutex(alloc_mutex);
3035 +#if defined(EAPI) && defined(EAPI_MM)
3037 + (void)ap_mm_unlock(mm);
3039 ap_unblock_alarms();
3045 +#if defined(EAPI_MM)
3046 +API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
3048 + return make_sub_pool_internal(p, 0);
3050 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
3052 + return make_sub_pool_internal(p, 1);
3055 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
3063 static void stack_var_init(char *s)
3065 @@ -487,6 +572,13 @@
3070 +int ap_shared_pool_possible(void)
3072 + return ap_mm_useable();
3077 static void dump_stats(void)
3079 @@ -519,14 +611,74 @@
3080 return permanent_pool;
3084 +void ap_init_alloc_shared(int early)
3086 +#if defined(EAPI_MM)
3089 + char *err1, *err2;
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();
3103 + err1 = "-unknown-";
3104 + err2 = strerror(errno);
3106 + err2 = "-unknown-";
3107 + fprintf(stderr, "Error: MM: %s: OS: %s\n", err1, err2);
3112 + /* process a lot later on startup */
3114 + ap_mm_permission(mm, (_S_IREAD|_S_IWRITE), ap_user_id, -1);
3116 + ap_mm_permission(mm, (S_IRUSR|S_IWUSR), ap_user_id, -1);
3119 +#endif /* EAPI_MM */
3123 +void ap_kill_alloc_shared(void)
3125 +#if defined(EAPI_MM)
3127 + ap_mm_destroy(mm);
3130 +#endif /* EAPI_MM */
3135 API_EXPORT(void) ap_clear_pool(struct pool *a)
3139 +#if defined(EAPI) && defined(EAPI_MM)
3141 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
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)
3149 + (void)ap_mm_unlock(mm);
3151 /* Don't hold the mutex during cleanups. */
3152 run_cleanups(a->cleanups);
3154 @@ -560,6 +712,10 @@
3158 +#if defined(EAPI) && defined(EAPI_MM)
3160 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3162 (void) ap_acquire_mutex(alloc_mutex);
3164 if (a->parent->sub_pools == a)
3165 @@ -570,6 +726,10 @@
3166 a->sub_next->sub_prev = a->sub_prev;
3168 (void) ap_release_mutex(alloc_mutex);
3169 +#if defined(EAPI) && defined(EAPI_MM)
3171 + (void)ap_mm_unlock(mm);
3174 free_blocks(a->first);
3175 ap_unblock_alarms();
3176 @@ -584,6 +744,30 @@
3177 return bytes_in_block_list(block_freelist);
3181 +API_EXPORT(int) ap_acquire_pool(pool *p, ap_pool_lock_mode mode)
3183 +#if defined(EAPI_MM)
3186 + return ap_mm_lock(mm, mode == AP_POOL_RD ? AP_MM_LOCK_RD : AP_MM_LOCK_RW);
3192 +API_EXPORT(int) ap_release_pool(pool *p)
3194 +#if defined(EAPI_MM)
3197 + return ap_mm_unlock(mm);
3204 /*****************************************************************
3205 * POOL_DEBUG support
3207 @@ -749,16 +933,31 @@
3211 +#if defined(EAPI) && defined(EAPI_MM)
3213 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
3215 (void) ap_acquire_mutex(alloc_mutex);
3217 +#if defined(EAPI) && defined(EAPI_MM)
3218 + blok = new_block(size, a->is_shm);
3220 blok = new_block(size);
3222 a->last->h.next = blok;
3225 blok->h.owning_pool = a;
3227 +#if defined(EAPI) && defined(EAPI_MM)
3228 + blok->h.is_shm = a->is_shm;
3231 (void) ap_release_mutex(alloc_mutex);
3232 +#if defined(EAPI) && defined(EAPI_MM)
3234 + (void)ap_mm_unlock(mm);
3237 ap_unblock_alarms();
3239 @@ -870,6 +1069,11 @@
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);
3248 ptr = realloc(ps->base, 2*size);
3250 fputs("Ouch! Out of memory!\n", stderr);
3251 @@ -890,9 +1094,21 @@
3252 cur_len = strp - blok->h.first_avail;
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);
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);
3263 nblok = new_block(2 * cur_len);
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);
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);
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);
3291 ps->got_a_new_block = 1;
3292 @@ -923,6 +1147,11 @@
3296 +#if defined(EAPI) && defined(EAPI_MM)
3298 + ps.base = ap_mm_malloc(mm, 512);
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';
3308 +#if defined(EAPI) && defined(EAPI_MM)
3310 + ptr = ap_mm_realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
3313 ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
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.
3324 +API_EXPORT(int) sendwithtimeout(int sock, const char *buf, int len, int flags)
3326 int sendwithtimeout(int sock, const char *buf, int len, int flags)
3331 @@ -193,8 +197,11 @@
3337 +API_EXPORT(int) recvwithtimeout(int sock, char *buf, int len, int flags)
3339 int recvwithtimeout(int sock, char *buf, int len, int flags)
3349 + if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
3351 rv = read(fb->fd_in, buf, nbyte);
3356 #if defined (WIN32) || defined(NETWARE)
3357 if (fb->flags & B_SOCKET) {
3359 + if (!ap_hook_call("ap::buff::recvwithtimeout", &rv, fb, buf, nbyte))
3361 rv = recvwithtimeout(fb->fd_in, buf, nbyte, 0);
3362 if (rv == SOCKET_ERROR)
3363 errno = WSAGetLastError();
3369 + if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
3371 #if defined (B_SFIO)
3372 rv = sfwrite(fb->sf_out, buf, nbyte);
3376 #if defined(WIN32) || defined(NETWARE)
3377 if (fb->flags & B_SOCKET) {
3379 + if (!ap_hook_call("ap::buff::sendwithtimeout", &rv, fb, buf, nbyte))
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);
3389 + fb->ctx = ap_ctx_new(p);
3395 @@ -1067,6 +1090,9 @@
3400 + if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
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 @@
3411 #endif /*_OSD_POSIX*/
3415 + * Invoke the `add_module' hook inside the now existing set
3416 + * of modules to let them all now that this module was added.
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);
3429 @@ -596,6 +610,21 @@
3435 + * Invoke the `remove_module' hook inside the now existing
3436 + * set of modules to let them all now that this module is
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);
3450 /* We are the top module, special case */
3451 @@ -985,6 +1014,27 @@
3452 const command_rec *cmd;
3453 module *mod = top_module;
3457 + * Invoke the `rewrite_command' of modules to allow
3458 + * they to rewrite the directive line before we
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);
3476 if ((l[0] == '#') || (!l[0]))
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;
3484 + s->ctx = ap_ctx_new(p);
3489 return ap_parse_vhost_addrs(p, hostname, s);
3490 @@ -1444,6 +1498,10 @@
3492 s->module_config = create_server_config(p, s);
3493 s->lookup_defaults = create_default_per_dir_config(p);
3496 + s->ctx = ap_ctx_new(p);
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
3505 int ap_listenbacklog;
3506 int ap_dump_settings = 0;
3507 API_VAR_EXPORT int ap_extended_status = 0;
3509 +API_VAR_EXPORT ap_ctx *ap_global_ctx;
3513 * The max child slot ever assigned, preserved across restarts. Necessary
3514 @@ -441,6 +444,30 @@
3519 +API_EXPORT(void) ap_add_config_define(const char *define)
3522 + var = (char **)ap_push_array(ap_server_config_defines);
3523 + *var = ap_pstrdup(pcommands, define);
3528 + * Invoke the `close_connection' hook of modules to let them do
3529 + * some connection dependent actions before we close it.
3531 +static void ap_call_close_connection_hook(conn_rec *c)
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);
3543 static APACHE_TLS int volatile exit_after_unblock = 0;
3545 @@ -1191,6 +1218,10 @@
3546 ap_log_transaction(log_req);
3550 + ap_call_close_connection_hook(save_req->connection);
3553 ap_bsetflag(save_req->connection->client, B_EOUT, 1);
3554 ap_bclose(save_req->connection->client);
3556 @@ -1199,6 +1230,9 @@
3557 ap_longjmp(jmpbuffer, 1);
3559 else { /* abort the connection */
3561 + ap_call_close_connection_hook(current_conn);
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 @@
3571 +API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x)
3573 unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x)
3578 @@ -1500,10 +1538,16 @@
3579 /* Send any leftover data to the client, but never try to again */
3581 if (ap_bflush(r->connection->client) == -1) {
3583 + ap_call_close_connection_hook(r->connection);
3586 ap_bclose(r->connection->client);
3590 + ap_call_close_connection_hook(r->connection);
3592 ap_bsetflag(r->connection->client, B_EOUT, 1);
3594 /* Close our half of the connection --- send the client a FIN */
3595 @@ -2203,6 +2247,9 @@
3597 /* Clear the pool - including any registered cleanups */
3598 ap_destroy_pool(pglobal);
3600 + ap_kill_alloc_shared();
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));
3610 + conn->ctx = ap_ctx_new(conn->pool);
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.
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);
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");
3635 + printf(" -D EAPI\n");
3638 + printf(" -D EAPI_MM\n");
3639 +#ifdef EAPI_MM_CORE_PATH
3640 + printf(" -D EAPI_MM_CORE_PATH=\"" EAPI_MM_CORE_PATH "\"\n");
3643 #ifdef BIG_SECURITY_HOLE
3644 printf(" -D BIG_SECURITY_HOLE\n");
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 *));
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);
3664 + ap_global_ctx = ap_ctx_new(NULL);
3669 @@ -4191,6 +4281,9 @@
3671 ap_sync_scoreboard_image();
3672 if (ap_scoreboard_image->global.running_generation != ap_my_generation) {
3674 + ap_call_close_connection_hook(current_conn);
3677 clean_child_exit(0);
3679 @@ -4219,6 +4312,9 @@
3684 + ap_call_close_connection_hook(current_conn);
3686 ap_bclose(conn_io); /* just close it */
3688 if (r && r->connection
3689 @@ -4229,6 +4325,9 @@
3694 + ap_call_close_connection_hook(current_conn);
3696 ap_bsetflag(conn_io, B_EOUT, 1);
3699 @@ -4953,16 +5052,31 @@
3704 + ap_init_alloc_shared(TRUE);
3707 ap_suexec_enabled = init_suexec();
3708 server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
3711 + ap_init_alloc_shared(FALSE);
3714 if (ap_configtestonly) {
3715 fprintf(stderr, "Syntax OK\n");
3717 + clean_parent_exit(0);
3722 if (ap_dump_settings) {
3724 + clean_parent_exit(0);
3730 child_timeouts = !ap_standalone || one_process;
3731 @@ -5098,6 +5212,10 @@
3732 ap_destroy_pool(r->pool);
3736 + ap_call_close_connection_hook(conn);
3742 @@ -5449,6 +5567,9 @@
3743 ap_kill_cleanups_for_socket(ptrans, csd);
3747 + ap_call_close_connection_hook(current_conn);
3749 ap_bclose(conn_io); /* just close it */
3751 if (r && r->connection
3752 @@ -5459,6 +5580,9 @@
3757 + ap_call_close_connection_hook(current_conn);
3759 ap_bsetflag(conn_io, B_EOUT, 1);
3762 @@ -6785,6 +6909,9 @@
3767 + ap_init_alloc_shared(TRUE);
3770 if (!ap_os_is_path_absolute(ap_server_confname)) {
3771 char *full_conf_path;
3772 @@ -6818,6 +6945,10 @@
3775 server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
3778 + ap_init_alloc_shared(FALSE);
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;
3791 + r->ctx = ap_ctx_new(r->pool);
3794 #ifdef CHARSET_EBCDIC
3795 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
3797 @@ -1174,6 +1178,11 @@
3798 rnew->read_body = REQUEST_NO_BODY;
3800 rnew->main = (request_rec *) r;
3803 + rnew->ctx = r->ctx;
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;
3817 + new->ctx = r->ctx;
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
3827 +** mod_define.c - Apache module for configuration defines ($xxx)
3829 +** Copyright (c) 1998-2000 Ralf S. Engelschall <rse@engelschall.com>
3830 +** Copyright (c) 1998-2000 Christian Reiber <chrei@en.muc.de>
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
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
3854 + * v1.0: Originally written in December 1998 by
3855 + * Ralf S. Engelschall <rse@engelschall.com> and
3856 + * Christian Reiber <chrei@en.muc.de>
3858 + * v1.1: Completely Overhauled in August 1999 by
3859 + * Ralf S. Engelschall <rse@engelschall.com>
3862 +#include "ap_config.h"
3863 +#include "ap_ctype.h"
3865 +#include "http_config.h"
3866 +#include "http_conf_globals.h"
3867 +#include "http_core.h"
3868 +#include "http_log.h"
3871 +#error "This module requires the Extended API (EAPI) facilities."
3875 + * The global table of defines
3878 +static table *tDefines = NULL; /* global table of defines */
3879 +static int bOnceSeenADefine = FALSE; /* optimization flag */
3882 + * Forward declaration
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 *);
3892 + * Character classes for scanner function
3895 + CC_ESCAPE, CC_DOLLAR, CC_BRACEOPEN, CC_BRACECLOSE,
3896 + CC_IDCHAR1, CC_IDCHAR, CC_OTHER, CC_EOS
3900 + * Scanner states for scanner function
3903 + SS_NONE, SS_SKIP, SS_DOLLAR, SS_TOKEN_BRACED,
3904 + SS_TOKEN_UNBRACED, SS_ERROR, SS_FOUND
3908 + * Default meta characters
3910 +#define DEFAULT_MC_ESCAPE "\\"
3911 +#define DEFAULT_MC_DOLLAR "$"
3912 +#define DEFAULT_MC_BRACEOPEN "{"
3913 +#define DEFAULT_MC_BRACECLOSE "}"
3916 + * Scanner for variable constructs $xxx and ${xxx}
3918 +static int DefineIndex(pool *p, char *cpLine, int *pos, int *len, char **cpVar)
3931 + cEscape = DEFAULT_MC_ESCAPE[0];
3932 + if ((cp = DefineFetch(p, "mod_define::escape")) != NULL)
3934 + cDefine = DEFAULT_MC_DOLLAR[0];
3935 + if ((cp = DefineFetch(p, "mod_define::dollar")) != NULL)
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];
3948 + for (cp = cpLine+(*pos); cc != CC_EOS; cp++) {
3949 + if (*cp == cEscape)
3951 + else if (*cp == cDefine)
3953 + else if (*cp == cBraceOpen)
3954 + cc = CC_BRACEOPEN;
3955 + else if (*cp == cBraceClose)
3956 + cc = CC_BRACECLOSE;
3957 + else if (ap_isalpha(*cp))
3959 + else if (ap_isdigit(*cp) || *cp == '_' || *cp == ':')
3961 + else if (*cp == '\0')
3984 + case CC_BRACEOPEN:
3985 + s = SS_TOKEN_BRACED;
3986 + *pos = cp-cpLine-1;
3991 + s = SS_TOKEN_UNBRACED;
3992 + *pos = cp-cpLine-1;
4004 + case SS_TOKEN_BRACED:
4010 + case CC_BRACECLOSE:
4012 + cp2 = ap_palloc(p, cp-*cpVar+1);
4013 + ap_cpystrn(cp2, *cpVar, cp-*cpVar+1);
4018 + cpError = ap_psprintf(p, "Illegal character '%c' in identifier", *cp);
4023 + case SS_TOKEN_UNBRACED:
4030 + cp2 = ap_palloc(p, cp-*cpVar+1);
4031 + ap_cpystrn(cp2, *cpVar, cp-*cpVar+1);
4041 + if (s == SS_ERROR) {
4042 + fprintf(stderr, "Error\n");
4045 + else if (s == SS_FOUND) {
4054 + * Determine the value of a variable
4056 +static char *DefineFetch(pool *p, char *cpVar)
4060 + /* first try out table */
4061 + if ((cpVal = (char *)ap_table_get(tDefines, (char *)cpVar)) != NULL)
4063 + /* second try the environment */
4064 + if ((cpVal = getenv(cpVar)) != NULL)
4070 + * Expand a variable
4072 +static char *DefineExpand(pool *p, char *cpToken, int tok_len, char *cpVal)
4075 + int val_len, rest_len;
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);
4089 + * The EAPI hook which is called after Apache has read a
4090 + * configuration line and before it's actually processed
4092 +static char *DefineRewriteHook(cmd_parms *cmd, void *config, const char *line)
4104 + /* runtime optimization */
4105 + if (!bOnceSeenADefine)
4113 + * ....\$[a-zA-Z][:_a-zA-Z0-9]*....
4114 + * ....\${[a-zA-Z][:_a-zA-Z0-9]*}....
4117 + cpLine = (char *)line;
4119 + while (DefineIndex(p, cpLine, &pos, &len, &cpVar)) {
4120 +#ifdef DEFINE_DEBUG
4122 + char prefix[1024];
4123 + char marker[1024];
4125 + for (i = 0; i < pos; i++)
4128 + for (i = 0; i < len; i++)
4132 + "Found variable `%s' (pos: %d, len: %d)\n"
4135 + cpVar, pos, len, cpLine, prefix, marker);
4138 + if (cpBuf == NULL) {
4139 + cpBuf = ap_palloc(p, MAX_STRING_LEN);
4140 + ap_cpystrn(cpBuf, line, MAX_STRING_LEN);
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);
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);
4164 + * Implementation of the `Define' configuration directive
4166 +static const char *cmd_define(cmd_parms *cmd, void *config,
4167 + char *cpVar, char *cpVal)
4169 + if (tDefines == NULL)
4170 + DefineInit(cmd->pool);
4171 + ap_table_set(tDefines, cpVar, cpVal);
4172 + bOnceSeenADefine = TRUE;
4177 + * Module Initialization
4180 +static void DefineInit(pool *p)
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);
4196 +static void DefineCleanup(void *data)
4198 + /* reset private variables when config pool is cleared */
4200 + bOnceSeenADefine = FALSE;
4205 + * Module Directive lists
4207 +static const command_rec DefineDirectives[] = {
4208 + { "Define", cmd_define, NULL, RSRC_CONF|ACCESS_CONF, TAKE2,
4209 + "Define a configuration variable" },
4214 + * Module API dispatch list
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 */
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
4246 static int proxy_fixup(request_rec *r)
4253 if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0)
4255 @@ -221,6 +224,14 @@
4256 url = &r->filename[6];
4258 /* canonicalise each specific scheme */
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)
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)
4273 ap_proxy_garbage_init(r, p);
4275 + ap_hook_use("ap::mod_proxy::init",
4276 + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p);
4282 +static void proxy_addmod(module *m)
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);
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);
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);
4304 +static void proxy_remmod(module *m)
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);
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
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),
4325 + ents[i].hostname, ents[i].port,
4326 + ents[i].protocol) || rc == DECLINED) {
4328 if (r->method_number == M_CONNECT)
4329 rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
4339 /* an error or success */
4340 if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
4341 @@ -390,6 +447,14 @@
4344 /* handle the scheme */
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),
4350 + NULL, 0, scheme) && rc != DECLINED)
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 */
4361 + ,proxy_addmod, /* EAPI: add_module */
4362 + proxy_remmod, /* EAPI: remove_module */
4363 + NULL, /* EAPI: rewrite_command */
4364 + NULL /* EAPI: new_connection */
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
4373 const char *urlptr = NULL;
4374 const char *datestr;
4375 struct tbl_do_args tdo;
4380 void *sconf = r->server->module_config;
4381 proxy_server_conf *conf =
4382 @@ -207,6 +210,12 @@
4383 return HTTP_BAD_REQUEST;
4385 destport = DEFAULT_HTTP_PORT;
4387 + ap_hook_use("ap::mod_proxy::http::handler::set_destport",
4388 + AP_HOOK_SIG2(int,ptr),
4392 strp = strchr(urlptr, '/');
4394 desthost = ap_pstrdup(p, urlptr);
4395 @@ -243,12 +252,18 @@
4396 err = ap_proxy_host2addr(proxyhost, &server_hp);
4398 return DECLINED; /* try another */
4400 + peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
4404 server.sin_port = htons(destport);
4405 err = ap_proxy_host2addr(desthost, &server_hp);
4407 return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
4409 + peer = ap_psprintf(p, "%s:%u", desthost, destport);
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);
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);
4430 ap_hard_timeout("proxy send", r);
4431 ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
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);
4444 + ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
4448 if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
4449 ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
4451 ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
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
4460 typedef const char *(*item_key_func) (request_rec *, char *);
4468 int condition_sense;
4469 @@ -554,15 +557,36 @@
4474 +static struct log_item_list *find_log_func(pool *p, char k)
4476 static struct log_item_list *find_log_func(char k)
4481 + struct log_item_list *lil;
4484 for (i = 0; log_item_keys[i].ch; ++i)
4485 if (k == log_item_keys[i].ch) {
4486 return &log_item_keys[i];
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));
4498 + lil->want_orig_default = 0;
4506 @@ -688,7 +712,11 @@
4511 + l = find_log_func(p, *s++);
4513 l = find_log_func(*s++);
4519 return ap_pstrcat(p, "Unrecognized LogFormat directive %",
4526 if (it->want_orig == -1) {
4527 it->want_orig = l->want_orig_default;
4528 @@ -758,6 +789,15 @@
4530 /* We do. Do it... */
4533 + if (item->func == 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);
4541 cp = (*item->func) (item->want_orig ? orig : r, item->arg);
4542 return cp ? cp : "-";
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 @@
4549 #endif /* ndef WIN32 && NETWARE*/
4553 + ap_hook_use("ap::mod_rewrite::lookup_variable",
4554 + AP_HOOK_SIG3(ptr,ptr,ptr),
4555 + AP_HOOK_DECLINE(NULL),
4560 if (result == NULL) {
4561 return ap_pstrdup(r->pool, "");
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
4571 + if ( modp->magic != MODULE_MAGIC_COOKIE_AP13
4572 + && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
4574 if (modp->magic != MODULE_MAGIC_COOKIE) {
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);
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);
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);
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>"
4606 + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>CPU</b></font></td>"
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>"
4617 +#else /* NO_PRETTYPRINT */
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);
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);
4624 +#endif /* NO_PRETTYPRINT */
4627 for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
4628 @@ -598,14 +619,19 @@
4629 vhost->server_hostname) : "(unavailable)");
4631 else { /* !no_table_report */
4632 +#ifndef NO_PRETTYPRINT
4633 + ap_rprintf(r,"<tr bgcolor=\"#ffffff\">");
4635 + ap_rprintf(r,"<tr>");
4637 if (score_record.status == SERVER_DEAD)
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);
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,
4650 @@ -665,12 +691,23 @@
4652 "<td>?<td nowrap>?<td nowrap>..reading.. </tr>\n\n");
4654 +#ifndef NO_PRETTYPRINT
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>"
4660 + score_record.client,
4661 + vhost ? vhost->server_hostname : "(unavailable)",
4662 + ap_escape_html(r->pool, score_record.request));
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));
4671 } /* no_table_report */
4672 } /* !short_report */
4673 } /* if (<active child>) */
4674 @@ -708,6 +745,12 @@
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);
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 */
4695 + ,NULL, /* EAPI: add_module */
4696 + NULL, /* EAPI: remove_module */
4697 + NULL, /* EAPI: rewrite_command */
4698 + NULL /* EAPI: new_connection */
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
4708 XML_UseParserAsHandlerArg
4709 +ap_add_config_define
4710 +ap_make_shared_sub_pool
4719 +ap_hook_unregister_I
4754 +ap_mm_core_permission
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