2_0_13 release branch
git-svn-id: https://svn.apache.org/repos/asf/perl/modperl/branches/release@1913168 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/2_0_13/BRANCHING b/2_0_13/BRANCHING
new file mode 100644
index 0000000..ccb962f
--- /dev/null
+++ b/2_0_13/BRANCHING
@@ -0,0 +1,81 @@
+This doc explains how to create/work/re-merge svn branches
+
+#######################################
+### PREREQUISITE ###
+#######################################
+
+You need to have svnmerge installed and working
+before you can proceed with rest of the instructions.
+
+You can find it here:
+
+http://www.orcaware.com/svn/wiki/Svnmerge.py
+
+#######################################
+### make a new branch ###
+#######################################
+
+we will create a branch mybranch
+
+branch:
+
+ svn copy https://svn.apache.org/repos/asf/perl/modperl/trunk \
+ https://svn.apache.org/repos/asf/perl/modperl/branches/mybranch \
+ -m "creating mybranch"
+
+check out:
+
+ svn co https://svn.apache.org/repos/asf/perl/modperl/branches/mybranch
+
+change externals to point to the new A-T branch (if one was done)
+
+ svn propedit svn:externals .
+
+initialize svnmerge tracking in the branch (if you plan to pull trunk/ changes into the branch)
+
+mybranch/ $> svnmerge init
+property 'svnmerge-integrated' set on '.'
+mybranch/ $> svn ci -F svnmerge-commit-message.txt
+
+
+initialize svnmerge tracking on the trunk:
+
+trunk/ $> svnmerge init https://svn.apache.org/repos/asf/perl/modperl/branches/mybranch
+property 'svnmerge-integrated' set on '.'
+mybranch/ $> svn ci -F svnmerge-commit-message.txt
+
+
+##############################################
+### merging changes from branch to brahch ###
+##############################################
+
+Work from a clean checkout of the branch you want to merge *to*
+
+Check on the availability of changes to merge
+
+$> svnmerge avail -b -l
+
+------------------------------------------------------------------------
+r584362 | gozer | 2007-10-12 21:00:47 -0700 (Fri, 12 Oct 2007) | 1 line
+Changed paths:
+ A /perl/modperl/branches/mybranch (from /perl/modperl/trunk:584361)
+
+creating mybranch
+------------------------------------------------------------------------
+r584363 | gozer | 2007-10-12 21:05:32 -0700 (Fri, 12 Oct 2007) | 3 lines
+Changed paths:
+ M /perl/modperl/branches/mybranch
+
+Initialized merge tracking via "svnmerge" with revisions "1-584361" from
+https://svn.apache.org/repos/asf/perl/modperl/trunk
+
+Then merge the ones you want to merge
+
+$> svnmerge -r 584362-584363
+
+review the changes, fix conflicts, etc
+
+Check in the merged version
+
+$> svn ci -F svnmerge-commit-message.txt
+
diff --git a/2_0_13/CONTRIBUTING.md b/2_0_13/CONTRIBUTING.md
new file mode 100644
index 0000000..b507419
--- /dev/null
+++ b/2_0_13/CONTRIBUTING.md
@@ -0,0 +1,59 @@
+# How to Contribute
+
+Help with mod_perl is always welcome. You do not have to know any code
+to help out - we also need help testing, answering questions, improving
+documentation, etc.
+
+
+## Issues
+
+Bugs and problems can be reported at:
+
+https://rt.cpan.org/Dist/Display.html?Name=mod_perl
+
+which can be accessed from the "Issues" link in the left-hand menu on
+the metacpan.org page, https://metacpan.org/pod/mod_perl2 .
+
+(Note: You will need to log in to https://rt.cpan.org in order to get
+the "Report a new bug" button on the bug tracker page.)
+
+
+### Discussions
+
+There is a low-volume mailing list for mod_perl users and developers to
+share ideas, solve problems and discuss things related to mod_perl and
+the Apache::* modules.
+
+Send an email to <modperl@perl.apache.org>. Before doing so, you should
+subscribe by sending an email to <modperl-subscribe@perl.apache.org>.
+Send an email to <modperl-unsubscribe@perl.apache.org> to unsubscribe.
+
+There is also a low-volume mailing list for discussions about the
+development of the core mod_perl.
+
+Send an email to <dev@perl.apache.org>. Before doing so, you should
+subscribe by sending an email to <dev-subscribe@perl.apache.org>.
+Send an email to <dev-unsubscribe@perl.apache.org> to unsubscribe.
+
+
+## Testing
+
+You can help by testing mod_perl as widely as possible. Running the
+tests on a wide variety of platforms, Apache httpd versions, Perl
+versions and other factors is a great help in uncovering problems and
+improving mod_perl.
+
+
+## Code development
+
+Development happens in a Subversion repo. The canonical location is
+currently at:
+
+https://svn.apache.org/repos/asf/perl/
+
+The current mod_perl 2.0 development branch is at modperl/trunk under
+the above URL.
+
+Create your own copy of that branch by running:
+
+svn co https://svn.apache.org/repos/asf/perl/modperl/trunk/ mod_perl2
diff --git a/2_0_13/Changes b/2_0_13/Changes
new file mode 100644
index 0000000..19bfa2d
--- /dev/null
+++ b/2_0_13/Changes
@@ -0,0 +1,3007 @@
+=encoding utf8
+
+=head1 NAME
+
+Changes - Apache mod_perl changes logfile
+
+=head1 CHANGES
+
+all changes without author attribution are by Doug MacEachern
+
+Also refer to the Apache::Test changes log file, at Apache-Test/Changes
+
+=over 3
+
+=item 2.0.13 October 21, 2023
+
+Use get_server_banner() instead of deprecated get_server_version() in
+Apache2::Status. [Petr Písař <ppisar@redhat.com]
+
+Avoid generating APR precompiled headers. [Sam James <sam@gentoo.org>]
+
+Fix build for perl >= 5.37.1. [Jitka Plesnikova <jplesnik@redhat.com>]
+
+=item 2.0.12 January 30, 2022
+
+Add bug tracker information to README, and add CONTRIBUTING.md. [Steve Hay]
+
+Fix detection of APR's threading support on RHEL 8. [Petr Písař
+<ppisar@redhat.com>]
+
+Fix build for perl >= 5.33.7. [Leon Timmermans <fawaka@gmail.com>]
+
+Fix SIGSEGV crash due to wrong use of perl_parse(). [Charles Pigott
+<cpigott@rapitasystems.com>]
+
+Improve installation instructions for AIX. [Rainer Tammer
+<rainer.tammer@schulergroup.com>]
+
+=item 2.0.11 October 5, 2019
+
+Fix t/modules/apache_resource.t failures [Steve Hay]
+
+Fix [CVE-2011-2767] Arbitrary Perl code execution in the context of the user
+account via a user-owned .htaccess. Patch from bugs.debian.org #644169. [Jan
+Ingvoldstad <jani+debian-2011+@ifi.uio.no>]
+
+Fix potential test suite hangs due to pipelined response deadlocks. Patch
+from rt.cpan.org #82409. [Zefram <zefram@fysh.org>]
+
+Fix t/compat/request.t failures [Steve Hay]
+
+Fix use-after-free segfault in ap_server_config_defines seen on start-up on
+OpenBSD. [Found/fixed by Sam Vaughan/Joe Orton]
+
+Fix build with Perls earlier than 5.13.6. [Rainer Jung
+<rainer.jung@kippdata.de>]
+
+Fix filter/in_bbs_inject_header.t test failure with Apache 2.4.25+. [Stefan
+Fritsch <sf@sfritsch.de>]
+
+Fix apache/read.t test failure with Apache 2.4.25+. [Niko Tyni
+<ntyni@debian.org>]
+
+=item 2.0.10 October 27, 2016
+
+Declare MP_vtbl_env and MP_vtbl_envelem as 'extern' to fix linker errors on
+OSX/Darwin. [Michael Schout <mschout@gkg.net>]
+
+Automatically select the appropriate c89 option when modperl is being
+built with either gcc 5 or clang. [Klaus S. Madsen <ksm@jobindex.dk>]
+
+Fix non-threaded Perl 5.22.x build and tests. [Klaus S. Madsen
+<ksm@jobindex.dk>]
+
+Add support for Perl 5.22.x. [Niko Tyni <ntyni@iki.fi>, Steve Hay]
+
+=item 2.0.9 June 18, 2015
+
+Add note to README about MP_INLINE problem when building with GCC 5.
+[Niko Tyni <ntyni@debian.org>]
+
+Fix t/api/aplog.t for apr-1.5.2. [Steve Hay]
+
+Note that Perl 5.22.x is currently not supported. This is logged as
+CPAN RT#101962 and will hopefully be addressed in 2.0.10. [Steve Hay]
+
+Fix unthreaded build, which was broken in 2.0.9-rc2. [Steve Hay]
+
+Remove PerlInterpScope. This has not been working properly with threaded
+MPMs with httpd-2.4.x and the use-case of this directive was questionable.
+[Jan Kaluza]
+
+Allow running the test suite with httpd-2.4.x when mod_access_compat is not
+loaded. [Steve Hay]
+
+Add support for Apache httpd-2.4.x. [Torsten Foertsch, Jan Kaluza,
+Steve Hay, Gozer]
+
+Don't call modperl_threaded_mpm() et al. from XS code. Fixes Debian Bug
+#765174. [Niko Tyni <ntyni@debian.org>]
+
+Make sure modperl_interp_select uses r->server rather than the passed s
+parameter to find the interpreter pool to pull an interpreter from. This
+fixes an issue with vhosts with a separate interpreter pool and runtime
+dir-config merges that used to pull the interpreter from the wrong pool.
+[Torsten Foertsch]
+
+PerlInterpScope is now more advisory. Using $(c|r)->pnotes will bind
+the current interpreter to that object for it's lifetime.
+$(c|r)->pnotes_kill() can be used to prematurely drop pnotes and
+remove this binding. [Torsten Foertsch]
+
+Now correctly invokes PerlCleanupHandlers, even if they are the only
+handler type configured for that request [Torsten Foertsch]
+
+For threaded MPMs, change interpreter managment to a new, reference-counted
+allocation model. [Torsten Foertsch]
+
+Expose modperl_interp_pool_t via ModPerl::InterpPool, modperl_tipool_t
+via ModPerl::TiPool and modperl_tipool_config_t via ModPerl::TiPoolConfig
+[Torsten Foertsch]
+
+Expose modperl_interp_t via ModPerl::Interpreter [Torsten Foertsch]
+
+Fix t/compat/apache_file.t on Windows. Apache::File->tmpfile() wants TMPDIR
+or TEMP from the environment, or else defaults to /tmp. The latter is no
+good on Windows, so make sure the environment variables are passed through.
+(TEMP should be set to something suitable on Windows.) [Steve Hay]
+
+Fix t/api/err_headers_out.t with HTTP::Headers > 6.00. [Rolando
+<rolosworld@gmail.com>]
+
+Fix the build with VC++ and dmake (rather than nmake) on Windows. The
+Makefile generated by Apache2::Build uses shell commands for the manifest
+file, but neglected to tell dmake to use the shell. [Steve Hay]
+
+Don't write an 'rpm' target into the Makefile on Windows. It isn't relevant
+on Windows, and the (hard-coded, not MakeMaker-generated) recipe group has
+syntax which dmake doesn't understand. [Steve Hay]
+
+=item 2.0.8 April 17, 2013
+
+Perl 5.16.3's fix for a rehash-based DoS makes it more difficult to invoke
+the workaround for the old hash collision attack, which breaks mod_perl's
+t/perl/hash_attack.t. Patch from rt.cpan.org #83916 improves the fix
+previously applied as revision 1455340. [Zefram]
+
+On Perl 5.17.6 and above, hash seeding has changed, and HvREHASH has
+disappeared. Patch to update mod_perl accordingly from rt.cpan.org #83921.
+[Zefram]
+
+Restore build with Perl 5.8.1, 5.8.2 etc: take care to use
+$Config{useithreads} rather than $Config{usethreads}, and supply definitions
+of Newx and Newxz as necessary. [Steve Hay]
+
+On Perl 5.17.9, t/apache/read2.t fails because an "uninitialized value"
+warning is generated for the buffer being autovivified. This is because
+the sv_setpvn() that's meant to vivify the buffer doesn't perform set
+magic; the warning is generated by the immediately following SvPV_force().
+Patch to fix this from rt.cpan.org #83922. [Zefram]
+
+Fix t/perl/hash_attack.t to work with Perl 5.14.4, 5.16.3 etc, which
+contain a fix for CVE-2013-1667 (memory exhaustion with arbitrary hash
+keys). This resolves rt.perl.org #116863, from where the patch was taken.
+[Hugo van der Sanden]
+
+use APR::Finfo instead of Perl's stat() in ModPerl::RegistryCooker to
+generate HTTP code 404 even if the requested filename contains newlines
+[Torsten]
+
+Remove all uses of deprecated core perl symbols. [Steve Hay]
+
+Add branch release tag to 'make tag' target. [Phred]
+
+=item 2.0.7 June 5, 2012
+
+Fix breakage caused by removal of PL_uid et al from perl 5.16.0. Patch from
+rt.cpan.org #77129. [Zefram]
+
+=item 2.0.6 April 24, 2012
+
+Preserve 5.8 compatibility surrounding use of MUTABLE_CV [Adam Prime]
+
+Move code after declarations to keep MSVC++ compiler happy. [Steve Hay]
+
+Adopt modperl_pcw.c changes from httpd24 branch. [Torsten Foertsch]
+
+Pool cleanup functions must not longjmp. Catch these exceptions and turn
+them into warnings. [Torsten Foertsch]
+
+Fix a race condition in our tipool management.
+See http://www.gossamer-threads.com/lists/modperl/dev/104026
+Patch submitted by: SalusaSecondus <salusa@nationstates.net>
+Reviewed by: Torsten Foertsch
+
+Ensure that MP_APXS is set when building on Win32 with MP_AP_PREFIX,
+otherwise the bundled Reload and SizeLimit builds will fail to find a
+properly configured Test environment.
+[Steve Hay]
+
+Fix a few REFCNT bugs.
+Patch submitted by: Niko Tyni <ntyni@debian.org>
+Reviewed by: Torsten Foertsch
+
+Correct the initialization of the build config in ModPerl::MM. The global
+variable was only being set once on loading the module, which was before
+Apache2::BuildConfig.pm had been written, leading to cwd and MP_LIBNAME
+being unset when writing the Reload and SizeLimit makefiles.
+[Steve Hay]
+
+Discover apr-2-config from Apache 2.4 onwards. [Gozer]
+
+Apache 2.4 and onwards doesn't require linking the MPM module directly in
+the httpd binary anymore. APXS lost the MPM_NAME query, so we can't assume
+a given MPM anymore. Introduce a fake MPM 'dynamic' to represent this.
+[Torsten Foertsch, Gozer]
+
+Perl 5.14 brought a few changes in Perl_sv_dup() that made a threaded apache
+segfault while cloning interpreters.
+[Torsten Foertsch]
+
+PerlIOApache_flush() and mpxs_Apache2__RequestRec_rflush() now no longer throw
+exceptions when modperl_wbucket_flush() fails if the failure was just a reset
+connection or an aborted connection. The failure is simply logged to the error
+log instead. This should fix cases of httpd.exe crashing when users press the
+Stop button in their web browsers.
+[Steve Hay]
+
+Fixed a few issues that came up with LWP 6.00:
+- t/response/TestAPI/request_rec.pm assumes HTTP/1.0 but LWP 6 uses 1.1
+- t/api/err_headers_out.t fails due to a bug somewhere in LWP 6
+- t/filter/TestFilter/out_str_reverse.pm sends the wrong content-length header
+[Torsten Foertsch]
+
+Bugfix: Apache2::ServerUtil::get_server{description,banner,version} cannot
+be declared as perl constants or they won't reflect added version components
+if Apache2::ServerUtil is loaded before the PostConfig phase. Now, they
+are ordinary perl functions. [Torsten Foertsch]
+
+Check for the right ExtUtils::Embed version during build [Torsten Foertsch]
+
+Take a lesson from rt.cpan.org #66085 and pass LD_LIBRARY_PATH if mod_env
+is present. Should prevent test failures on some platforms.
+[Fred Moyer]
+
+
+=item 2.0.5 February 7, 2011
+
+The mod_perl PMC dedicates this release of mod_perl to Randy Kobes, who
+passed away in September 2010. Randy was a member of the mod_perl project
+management committee and a co-author of the mod_perl Developer's Cookbook.
+His work helped many Windows mod_perl users. His work with ppm files, and
+Win32 perl users will be sorely missed. He was kind, bright, and always
+willing to lend a hand on the mod_perl user's list.
+
+Prepare modperl for the upcoming perl 5.14 [Torsten Foertsch]
+
+Add lib/ModPerl/MethodLookup.pm to MANIFEST via lib/ModPerl/Manifest.pm
+RT #48103 reported by MARKLE@cpan.org
+[Fred Moyer]
+
+PerlIOApache_write() now throws an APR::Error object, rather than just a string
+error, if modperl_wbucket_write() fails.
+[Steve Hay]
+
+Authentication tests fail with LWP 5.815 and later
+[Doug Schrag]
+
+Concise test won't perform unless StatusTerse is set to ON
+[Doug Schrag]
+
+Look for a usable apxs in $ENV{PATH} if all other options fail, then prompt the user for one.
+[Phred]
+
+Work around bootstrap warnings when Apache2::BuildConfig has not been created yet.
+[Phred]
+
+Remove Apache::test compatibility (part of mod_perl 1.2.7), that code causes build issues and is 4 versions out of date.
+[Phred]
+
+Make sure perl is built either with multiplicity and ithreads or without
+both [Theory, Torsten]
+
+Support for "install_vendor" and "install_site" make targets [Torsten]
+
+Run tests on bundled pure perl Apache::* modules [Gozer, Phred]
+
+Implement a mini-preprocess language for map-files in xs/maps.
+[Torsten Foertsch]
+
+Implement APR::Socket::fileno [Torsten Foertsch]
+
+Export PROXYREQ_RESPONSE, a missing PROXYREQ_* constant [Gozer]
+
+Make sure standard file descriptors are preserved by the perl-script
+handler [Torsten Foertsch]
+
+Fix the filter init handler attribute check in
+modperl_filter_resolve_init_handler() [Torsten Foertsch]
+
+Make sure buffer is a valid SV in modperl_filter_read() [Torsten Foertsch]
+
+Move modperl_response_finish() out of modperl_response_handler_run in
+mod_perl.c [Torsten Foertsch]
+
+"MODPERL_INC= now correctly supported as an argument to Makefile.PL"
+[Torsten Foertsch]
+
+Fix an XSS issue in Apache2::Status reported by Richard J. Brain
+<richard@procheckup.com>. [Torsten Foertsch]
+
+Add NOTICE file to the distribution. [Joe Schaefer]
+
+Make sure Apache2::RequestIO::read doesn't clear the buffer on end of
+file and handle negative offsets and offsets that are larger than
+the current string length. [Torsten Foertsch]
+
+Fix a problem that could make APR::XSLoader and Apache2::XSLoader
+load the wrong shared library. [Torsten Foertsch]
+
+Fix compilation when using a non-threaded APR.
+[Gozer, Philip M. Gollucci]
+
+Make sure mod_perl's own ChildInitHandlers are run before user
+supplied ones. This fixes the incorrectly reported value of $$
+at ChildInit time [Gozer]
+
+=item 2.0.4 April 16, 2008
+
+Fix $r->location corruption under certain conditions
+[Gozer]
+
+Fix a crash when spawning Perl threads under Perl 5.10
+[Gozer]
+
+Fix erratic behaviour when filters were used with Perl 5.10
+[Gozer]
+
+Fix problems with redefinitions of perl_free as free and perl_malloc
+as malloc on Win32, as described at
+ http://marc.info/?l=apache-modperl&m=119896407510526&w=2
+[Tom Donovan]
+
+Fix a crash when running a sub-request from within a filter where
+mod_perl was not the content handler. [Gozer]
+
+Refactor tests to use keepalives instead of same_interp [Gozer, Phred]
+
+Apache2::Reload has been moved to an externally maintained
+CPAN distribution [Fred Moyer <fred@redhotpenguin.com>]
+
+PerlCleanupHandler are now registered with a subpool of $r->pool,
+instead of $r->pool itself, ensuring they run _before_ any other
+$r->pool cleanups [Torsten Foertsch]
+
+Fix a bug that would prevent pnotes from being cleaned up properly
+at the end of the request [Torsten Foertsch]
+
+On Win32, embed the manifest file, if present, in mod_perl.so,
+so as to work with VC 8 [Steve Hay, Randy Kobes]
+
+Expose apr_thread_rwlock_t with the APR::ThreadRWLock module
+[Torsten Foertsch]
+
+Don't waste an extra interpreter anymore under threaded MPMs when using a
+modperl handler [Torsten Foertsch]
+
+Fix a bug that could cause a crash when using $r->push_handlers() multiple
+times for a phase that has no configured handlers [Torsten Foertsch]
+
+Catch up with some httpd API changes
+ 2.2.4:
+ The full server version information is now included in the error log at
+startup as well as server status reports, irrespective of the setting
+of the ServerTokens directive. ap_get_server_version() is now
+deprecated, and is replaced by ap_get_server_banner() and
+ap_get_server_description(). [Jeff Trawick]
+
+ 2.3.0:
+ap_get_server_version() has been removed. Third-party modules must
+now use ap_get_server_banner() or ap_get_server_description().
+[Gozer]
+
+fixed Apache2::compat Apache2::ServerUtil::server_root() resolution
+issues [Joshua Hoblitt]
+
+*) SECURITY: CVE-2007-1349 (cve.mitre.org)
+fix unescaped variable interprolation in regular expression
+[Randal L. Schwartz <merlyn@stonehenge.com>, Fred Moyer <fred@redhotpenguin.com>]
+
+Make $r->the_request() writeable
+[Fred Moyer <fred@redhotpenguin.com>]
+
+fix ModPerl::RegistryCooker::read_script to handle all possible
+errors, previously there was a case where Apache2::Const::OK was
+returned on an error. [Eivind Eklund <eeklund@gmail.com>]
+
+a minor compilation warning resolved in modperl_handler_new_from_sv
+[Stas]
+
+a minor compilation warning resolved in modperl_gtop_size_string
+[Stas]
+
+Prevent direct use of _deprecated_ Apache2::ReadConfig in
+<Perl> sections with httpd Alias directives from
+incorrectly generating
+'The Alias directive in xxxxx at line y will probably never match'
+messages.
+[Philip M. Gollucci <pgollucci@p6m78g.com>]
+
+Prevent Apache2::PerSections::symdump() from returning invalid
+httpd.conf snippets like 'Alias undef'
+[Philip M. Gollucci <pgollucci@p6m78g.com>]
+
+Require B-Size 0.9 for Apache2::Status which fixes
+Can't call method "script_name" on an undefined value
+[Philip M. Gollucci <pgollucci@p6m78g.com>]
+
+-march=pentium4 or anything with an = in it in CCFLAGS or @ARGV
+that gets passed to xs/APR/APR/Makefile.PL broke the @ARGV
+parsing. I.E. FreeBSD port builds when users had CPUTYPE
+set in /etc/make.conf.
+[Philip M. Gollucci <pgollucci@p6m7g8.com>]
+
+Fixes to get bleed-ithread (5.9.5+) to comile again.
+[Philip M. Gollucci <pgollucci@p6m7g8.com>]
+
+=item 2.0.3 November 28, 2006
+
+Prevent things in %INC that are not stat() able
+from breaking Apache2::Status 'Loaded Modules'
+under fatal warnings.
+[Philip M. Gollucci <pgollucci@p6m7g8.com>]
+
+When using MP_AP_PREFIX on WIN32 make sure that its
+a valid directory.
+[Nikolay Ananiev <ananiev@thegdb.com>]
+
+Fix bug concerning 'error-notes' having no value on
+errordocument redirect.
+[Guy Albertelli II <guy@albertelli.com>]
+
+Multi-line $PerlConfig is now working [Gozer]
+
+PerlOptions None was previously incorrectly reported as invalid
+inside <VirtualHost> or <Directory> blocks.
+[Philip M. Gollucci]
+
+Require B::Size 0.07 and B::TerseSize 0.07 for Apache2::Status
+[Philip M. Gollucci]
+
+Apache2::Status was expecting B::TerseSize to return
+an op count for things that it didn't causing
+requests like http://localhost/perl-status/main?noh_b_package_size
+to cause 405s
+[Philip M. Gollucci]
+
+Updates for Win32 to allow building and testing on Apache/2.2:
+- use httpd.exe as the Apache binary name when installing apxs
+- use new apr library names (libapr-1.lib and libaprutil-1.lib)
+[Randy Kobes]
+
+Make sure that additional library paths are included in the build flags
+so that mod_perl will use the same versions of libraries that APR does.
+[Mike Smith <mike@mailchannels.com>]
+
+Added $r->connection->pnotes, identical to $r->pnotes, but
+for the entire lifetime of the connection
+[Geoffrey Young, Gozer]
+
+Fixed problems with add_config() and thread-safety: [Gozer]
+- $s->add_config is not allowed anymore after server startup
+- $r->add_config can only affect configuration for the current
+ request, just like .htaccess files do
+
+Make sure that LIBS and other MakeMaker command line flags are not
+ignored by the top level Makefile.PL and xs/APR/APR/Makefile.PL [Stas]
+
+Corrected a typo that would cause the corruption of $), the
+effective group id as Perl sees it [Gozer]
+
+Added support for httpd-2.2's new override_opts in Apache2::Access.
+Calls to add_config() now accept an override_opts value as the 4th
+argument. [Torsten Foertsch <torsten.foertsch@gmx.net>, Gozer]
+
+Fix 'PerlSwitches +inherit' that got broken somewhere along
+the way to 2.0. You can also use 'PerlOptions +InheritSwitches'
+for the same result. [Gozer]
+
+Add perl API corresponding to User and Group directives in httpd.conf:
+Apache2::ServerUtil->user_id and Apache2::ServerUtil->group_id
+[Stas]
+
+Apache2::Reload now first unloads all modified modules before
+trying to reload them. This way, inter-module dependencies
+are more likely to be correctly satisfied when reloaded
+[Javier Uruen Val <juruen@warp.es>, Gozer]
+
+$r->add_config() can now take an optionnal 3rd argument that
+specifies what pseudo <Location $path> the configuration is
+evaluated into [Torsten Foertsch <torsten.foertsch@gmx.net>]
+
+remove -DAP_HAVE_DESIGNATED_INITIALIZER and -DAP_DEBUG from
+MP_MAINTAINER mode to avoid collisions [Joe Orton]
+
+Back out r280262 which was causing Apache2::Reload to misbehave.
+[JT Smith <jt@plainblack.com>]
+
+Perl_do_open/close fixes to make mod_perl 2.0 compile with
+blead-perl@25889+ (5.9.3+) [Stas]
+
+Added Apache2::PerlSections->server, returning the server
+into which the <Perl> section is defined [Gozer]
+
+Require B::Size and B::TerseSize v0.06 for Apache2::Status
+options StatusTerse and StatusTerseSize which has now been
+updated to support the new mod_perl2 api post RC5.
+[Philip M. Gollucci]
+
+When using Apache2::PerlSections->dump, the configuration
+would print out in the correct order, but when the configuration was
+passed off to Apache the ordering was lost.
+[Scott Wessels <swessels@usgn.net>]
+
+=item 2.0.2 - October 20, 2005
+
+add :proxy import tag to Apache2::Const which exposes new
+constants PROXYREQ_NONE, PROXYREQ_PROXY, and PROXYREQ_REVERSE
+[Geoffrey Young]
+
+$0 Fixes : [Gozer]
+- Setting $0 works on Linux again
+- HP-UX and *BSDes show the correct process name instead of '-e'
+
+Fix a critical but trivial bug that would cause MP_MAINTAINER=1
+or MP_TRACE=1 builds to fail if not building against a threaded APR.
+Functions such as apr_os_thread_current() would not be linked in,
+but were expected to be.
+[Philip M. Gollucci]
+
+Add the output of ldd(unix/cygwin) and otool -L (darwin)
+for httpd to the mp2bug report script.
+[Philip M. Gollucci]
+
+Prevent tools such as Apache2::Status's Loaded Modules screen
+from displaying erroneous information about mod_perl.pm being loaded.
+[Stas, Philip M. Gollucci]
+
+Correctly set the version of ModPerl::MethodLookup, previously,
+it was not set because of the way it was Generating via ModPerl::WrapXS.
+[Philip M. Gollucci]
+
+Improve the detection of whether or not we are in an mp2 build tree.
+This allows usage of ExtUtils::MakeMaker options such as PREFIX to
+not break the probe of mp2 build trees.
+[Stas, Philip M. Gollucci]
+
+Add support for the newer Smaps (/proc/self/statm) on Linux
+systems that support it (i.e. linux-2.6.13-rc4-mm1)
+to accurately count the amount of shared memory.
+[Torsten Foertsch <torsten.foertsch gmx.net>]
+
+On cygwin some dlls might happen to be with identical base addresses
+and if you try to load both of them you'll get an error and you'll
+have to use the rebase utility to fix them. this fix should prevent
+this. [Nikolay Ananiev <ananiev@thegdb.com>]
+
+Fix an undefined warning in DSO builds when not using MP_APXS.
+[Nikolay Ananiev <ananiev@thegdb.com>]
+
+When running Makefile.PL with the MP_MAINTAINER=1 option
+add -Wdeclaration-after-statement if we are using gcc
+version 3.3.2 or higher and its not already part of the ccopts.
+[Philip M. Gollucci, Gozer]
+
+Several fixes to Apache2::Status
+[Philip M. Gollucci]
+
+When using Apache2::Reload and ReloadDebug is set to 'On',
+sort the output alphabetically [Philip M. Gollucci]
+
+croak in case a filter returns DECLINED after calling $f->read (as it
+is not supposed to happen) [Stas]
+
+another round of cygwin fixes [Nikolay Ananiev <ananiev@thegdb.com>]
+
+Multiple fixes to make mod_perl 2.0 work with blead-perl (5.9.3+)
+[Stas]
+
+t/modules/reload.t would fail if run more than 3 times, breaking
+smokes [Gozer]
+
+filter flushing now doesn't croak on connection reset
+(ECONNRESET/ECONNABORTED), but just logs the event on the 'info'
+level. [Stas]
+
+RPM Friendly builds : [Gozer]
+- make dist tarballs can now be built directly into RPMs with rpmbuild
+- Added a new target 'make rpm' to directly build rpms from a checkout
+
+
+
+=item 2.0.1 - June 17, 2005
+
+B::Terse has problems with XS code, so adjust Apache::Status to eval
+{} the code doing Syntax Tree Dump: syntax and execution order options
+[Stas]
+
+Fix a broken regexp in Apache2::Build::dir() on win32 that would
+incorrectly attempt to fully-qualify paths like c:/some/path
+[Nikolay Ananiev <ananiev@thegdb.com>]
+
+Fix the "No library found" warnings when building on win32 without
+apxs and MP_AP_PREFIX [Nikolay Ananiev <ananiev@thegdb.com>]
+
+The pure-perl ModPerl::Util::unload_package implementation was
+accidently deleting sub-stashes [Gozer]
+
+If running Makefile.PL unnatended (STDIN isn't a terminal or
+MP_PROMPT_DEFAULT=1), break out of potentially infinite prompt
+loops [Gozer]
+
+fix ModPerl::TestReport used by t/REPORT and mp2bug to use
+ExtUtils::MakeMaker's MM->parse_version to get the interesting
+packages version number, w/o trying to load them (which may fail if
+the environment is not right) [Stas]
+
+fix a bug in ModPerl::RegistryCooker: now stripping __(END|DATA)__
+only at the beginning of the line [Stas]
+
+APR::Base64 : [Torsten Foertsch <torsten.foertsch@gmx.net>]
+- fix encode_len() to return the length without accounting for the
+terminating '\0' as the C API does.
+- fix encode() to create the string of the correct length (previously
+was creating one too many)
+
+in mod_perl callbacks merge error-notes entries rather than store just
+the newest error [Mark <mark@immermail.com>]
+
+Expose Apache2::Const::EXEC_ON_READ (added to the :override group)
+[Stas]
+
+Fix a bug in custom directive implementation, where the code called
+from modperl_module_config_merge() was setting the global context
+after selecting the new interpreter which was leading to a segfault in
+any handler called thereafter, whose context was different
+beforehand. [Stas]
+
+
+
+=item 2.0.0 - May 20, 2005
+
+fix global anon_cnt double-initialization bug that was causing
+startup segfaults on OSX. [Gozer]
+
+fix the ap_install target in the top-level Makefile (used for static
+build) [Stas]
+
+Reintroduce a pure-Perl version of ModPerl::Util::unload_package()
+The problematic XS version is now called unload_package_xs() and
+not used by default [Gozer]
+
+More APR::Status wrappers: [Stas, Randy Kobes]
+- is_EOF
+- is_ECONNABORTED
+- is_ECONNRESET
+- is_TIMEUP
+
+make sure that the build picks up the include directories based on the
+apxs queries and only search the httpd source if $self->{MP_AP_PREFIX}
+was set. Earlier it was always picking the headers from the httpd
+source if it was available, which was resulting in the wrong headers
+if the installed httpd was different than the source that was found
+[Stas]
+
+introduce ModPerl::RegistryPrefork and ModPerl::PerlRunPrefork, which
+behave the same as ModPerl::Registry and ModPerl::PerlRun,
+respectively, but chdir to the script's directory like mod_cgi
+does. These two new handlers will refuse to load under threaded MPMs
+where chdir can't be used as it will affect all running threads [Stas]
+
+ModPerl::RegistryCooker::chdir_file_normal() now chdirs to the current
+script's directory or the specified directory as an argument, as it
+was planned in first place. Therefore switch ModPerl::Registry and
+ModPerl::PerlRun to us NOP for this method call. If chdir_file is
+mapped to chdir_file_normal(), then run() and
+convert_script_to_compiled_handler() now call chdir to the script's
+directory and at before returning go back to the server root. [Stas]
+
+prevent undef warnings in catfile() calls in Apache2::Build when
+called from the ModPerl-Registry tree [Stas]
+
+fix modperl_brigade_dump to use apr_file_printf() instead of
+fprintf(), which doesn't work everywhere [Stas]
+
+Fix a warning triggered by `ln` on Cygwin, when running perl
+Makefile.PL for a second time without previously running make
+clean. [Nikolay Ananiev <ananiev@thegdb.com>]
+
+When compiling a static mod_perl and
+MP_AP_CONFIGURE="--with-apr=/some/path" argument is given, Apache will
+use the apr-config at the given path, but mod_perl was using the
+default at "srclib/apr/.libs". Fix that [Nikolay Ananiev <ananiev@thegdb.com>]
+
+Show MP_APU_CONFIG as an argument to Makefile.PL in the Usage
+menu. [Nikolay Ananiev <ananiev@thegdb.com>]
+
+Makefile.PL: fix the pre-rename mp2 install diagnostics code, to use
+the mp version of 1.999xx and not 1.999_xx, as the latter is
+unsuitable for numerical comparison, also fix the name of the reported
+conflicting directory [Stas].
+
+add APR::Status::is_(EACCES|ENOENT), and use in ModPerl::RegistryCooker
+to return, as appropriate, Apache2::Const::(FORBIDDEN|NOT_FOUND),
+based on $@. Also remove a check in modperl_slurp_filename
+of src/modules/perl/modperl_util.c to enable $@ to be set when
+opening or reading a file fails. This fixes a bug on Win32, revealed
+in 404.t and redirect.t of the ModPerl-Registry tests, as reported
+by Steve Hay and Markus Wichitill [Stas, Randy Kobes]
+
+link Apache2::* and ModPerl::* to mod_perl.a and DynaLoader.a, but
+-lmod_perl and -lDynaLoader don't work, and we can't supply the full
+paths, because MakeMaker doesn't allow this. I workaround this by
+making a symlink to mod_perl.a (called libmod_perl.a) and copy
+DynaLoader.a to libDynaLoader.a (I don't create a symlink, because,
+when running make clean, the real DynaLoader.a may get deleted). The
+APR::* extensions are not affected, because in both cases we link them
+against aprext. Also other small fixes are added. [Nikolay Ananiev
+<ananiev@thegdb.com>]
+
+
+
+
+=item 1.999_23 - May 3, 2005
+
+fix Apache2::Build::dynamic_link_MSWin32 to generate a new line after
+dynamic_link code in Makefile [Nikolay Ananiev <ananiev@thegdb.com>]
+
+fix a warning in Apache2::Build::build_config() when building
+with MP_STATIC_EXTS=1 [Nikolay Ananiev <ananiev@thegdb.com>]
+
+improving DSO support on cygwin. The problem with cygwin is that it
+behaves like windows (it's a posix layer over windows after
+all). That's why we need to supply all symbols during linking time
+just like on win32, by adding -lapr-0 -laprutil-0 and -lhttpd. On
+windows, Apache supplies all the three libraries and it's easy to
+link, but on cygwin apache doesn't play nice and doesn't supply
+libhttpd. This change adds libapr and libaprutil. [Nikolay Ananiev
+<ananiev@thegdb.com>]
+
+improve the diagnostics when detecting mp2 < 1.999022, tell the user
+which files and/or dirs need to be removed [Stas]
+
+restore the DESTDIR support partially nuked by the apache2 rename
+branch [Torsten Förtsch <torsten.foertsch gmx.net>]
+
+add APR::Status to provide functions corresponding to the
+APR_STATUS_IS_* macros of apr_errno.h, especially those composites
+like APR_STATUS_IS_EAGAIN(s) which are satisfied by more than one
+specific error condition. Presently only APR_STATUS_IS_EAGAIN is
+provided [Randy Kobes]
+
+fix the generation of the manpages for .pm files from sub-projects
+like ModPerl-Registry (previously was creating manpage files like
+.::ModPerl::PerlRun.3) [Stas]
+
+fix the pod2man'ification part of 'make install' (using POD2MAN_EXE
+instead of POD2MAN Makefile macro) [Stas]
+
+
+=item 1.999_22 - April 14, 2005
+
+ ******************** IMPORTANT ********************
+ this version of mod_perl is completely incompatible
+ with prior versions of mod_perl, both 1.XX and
+ 1.99_XX. Please read the below changes carefully.
+ ***************************************************
+
+remove MP_INST_APACHE2 installation option and Apache2.pm - all
+mod_perl related files will now be installed so they are visible
+via standard @INC. also, refuse to install over mod_perl 2 versions
+less than 1.999_22. [Geoffrey Young]
+
+s/Apache::/Apache2::/g and s/mod_perl/mod_perl2/g in all module
+APIs. so, Apache::RequestRec is now Apache2::RequestRec,
+Apache::compat is now Apache2::compat, and so on. [joes]
+
+move all Apache:: constants to Apache2::Const and all APR:: constants
+to APR::Const. for example, Apache:OK is now Apache2::Const::OK and
+APR::SUCCESS is now APR::Const::SUCCESS. [Geoffrey Young]
+
+add $ENV{MOD_PERL_API_VERSION} as something that clearly distinguishes
+which mod_perl version is being used at request time. [Geoffrey Young]
+
+rename Apache->request() to Apache2::RequestUtil->request(), and
+Apache->server() to Apache2::ServerUtil->server()
+[Geoffrey Young]
+
+fix Apache2::Status which was bailing out on trying to load modules
+with dev versions like 2.121_02 [Stas]
+
+When parsing Makefile.PL MP_* options, handle correctly the MP_FOO=0
+entries [Philip M. Gollucci <pgollucci@p6m7g8.com>]
+
+init the anonsub hash for base perl and each vhost +Parent (previously
+was init'ed only for the base perl) [Stas]
+
+fix a bug when a non-threaded perl is used and anonymous sub is pushed
+at the server startup (the CV wasn't surviving) [Stas]
+
+Make sure that CPAN shell doesn't triple over usage of
+$ExtUtils::MakeMaker::VERSION [Randy Kobes]
+
+Apache2::RequestRec->new now sets $r->request_time [Stas]
+
+remove CGI.pm and Apache::Request dependencies from Apache2::Status
+since they weren't used at all [Geoffrey Young]
+
+Fixes for Apache2::Reload's touchfile feature (return Apache2::Const::OK
+instead of 1) [Chris Warren <chwarren@cisco.com>]
+
+cygwin fixes: [Nikolay Ananiev <ananiev@thegdb.com>]
+- doesn't like XS wrapper starting with 'static'
+- need to compile everything with -DCYGWIN
+
+ModPerl::RegistryCooker API change: s/rewrite_shebang/shebang_to_perl/
+the new API now returns the string to prepend before the rest of the
+script, instead of rewriting the content, which is both faster and
+doesn't mislead the perl debugger [Dominique Quatravaux
+<dom@idealx.com>]
+
+Starting from ExtUtils::MakeMaker 6.26 went back to pm_to_blib target
+from pm_to_blib.ts introduced in 6.22, so needed to fix the glue_pod
+target, so install will work correctly [Stas]
+
+Syntax errors in <Perl> sections were not correctly caught and
+reported. [Gozer]
+
+when building mp2 EU::MM looks into Apache-Test/MANIFEST and complains
+about the missing Apache-Test/META.yml (which is indeed not included
+in the modperl package due to the PAUSE problems of dealing with more
+than one META.yml. Solution: Exclude Apache-Test/MANIFEST from
+mod_perl distribution package. [Stas]
+
+ModPerl::Registry no longer checks for -x bit (we don't executed
+scripts anyway), and thus works on acl-based filesystems. Also
+replaced the -r check with a proper error handling when the file is
+read in. [Damon Buckwalter <buckwad@gmail.com>]
+
+Apache2::RequestUtil::slurp_filename now throws an APR::Error exception
+object (before it was just croaking). [Stas]
+
+fix APR::Error's overload of '==' (it was always returning true
+before), and add the corresponding '!=' [Stas]
+
+if $r->document_root was modified, restore it at the end of request
+[joes]
+
+Apache2::ServerRec method which set the non-integer fields in the
+server_rec, now copy the value from the perl scalar, so if it changes
+or goes out of scope the C struct is not affected. Using internal perl
+variables to preserve the value, since using the server pool to
+allocate the memory will mean a memory leak [Stas]
+
+add the escape_url entry in the ModPerl::MethodLookup knowledgebase
+[Stas]
+
+Apache2::SubProcess::spawn_proc_prog now can be called in a void
+context, in which case all the communication std pipes will be closed
+[Stas]
+
+fix a bug in $r->document_root, which previously weren't copying the
+new string away [Stas]
+
+introduce a new build option MP_AP_DESTDIR to aid package builders
+direct the Apache-specific files to the right place. [Cory Omand
+<Cory.Omand@Sun.COM>]
+
+Fix bug in modperl_package_clear_stash() segfaulting when
+encountering declared but not yet defined subroutines.
+[Steve Hay <steve.hay@uk.radan.com>, Gozer]
+
+win32 needs PERL_SYS_INIT3/PERL_SYS_TERM calls [Steve Hay
+<steve.hay@uk.radan.com>]
+
+Fix broken MP_STATIC_EXTS=1 build. [Gozer]
+
+Perl -Duse64bit fix. Pointers can't just be generically
+casted from/to IVs. Use PTR2IV/INT2PTR instead. [Gozer]
+
+Perl -Duse64bit fix. apr_size_t pointers can't just be generically
+casted from/to UVs. Use PTR2UV/INT2PTR instead. [Gozer]
+
+fix a bug in Apache2::Build::dir: If the right directory isn't found in
+the for loop $dir still contains a > value, so the ||= has no
+effect. [Nick Wellnhofer <wellnhofer@aevum.de>]
+
+
+
+=item 1.999_21 - January 22, 2005
+
+PerlPostConfigRequire was trying to detect missing files early on,
+but without searching thru @INC, causing false negatives. Better off
+skipping that check and leave it to modperl_require_file() to report
+problems with finding the file. [Patrick LeBoutillier
+<patrick.leboutillier@gmail.com>, Gozer]
+
+add a perl bug workaround: with USE_ITHREADS perl leaks pthread_key_t
+on every reload of libperl.{a,so} (it's allocated on the very first
+perl_alloc() and never freed). This becomes a problem on apache
+restart: if the OS limit is 1024, 1024 restarts later things will
+start crashing [Gisle Aas <gisle@ActiveState.com>, Stas]
+
+on Irix mod_perl.so needs to see the libperl.so symbols, which
+requires the -exports option immediately before -lperl. [Gordon Lack
+<gml4410@ggr.co.uk>]
+
+pool arguments to startup and connection callbacks must be blessed
+into APR::Pool and not Apache::Pool class [joes]
+
+Make PerlSetEnv, PerlPassEnv and %ENV in PerlRequre, PerlModule,
+PerlConfigRequire and PerlPostConfigRequire affect each other, so a
+change in one of these is immediately seen in the others. [Pratik
+<pratiknaik gmail.com>, Stas]
+
+
+
+=item 1.999_20 - January 5, 2005
+
+the autogenerated modules (and some implemented in xs/ modules) are
+now getting the same version number as $mod_perl::VERSION (the
+exception are APR modules which get 0.009_000 for now). [Stas]
+
+until we figure out how to tell PAUSE index about versions of the
+autogenerated modules, create a fake module which lists all the
+autogenerated modules and their versions and include that in the
+distro. [Stas]
+
+moving to the triplet version notation, which requires us to bump 1.99
+=> 1.999 so 1.999020 (mp2) > 1.29 (mp1). [Stas]
+Now we are gong to have:
+ $mod_perl::VERSION : "1.099020"
+ int $mod_perl::VERSION : 1.09902
+ $mod_perl::VERSION_TRIPLET: 1.99.20
+
+<Perl> and PerlPostConfigRequires were leaking some memory at
+startup. Use parms->temp_pool instead of parms->pool for temporary
+memory allocations. [Gozer]
+
+deal with a situation where an object is used to construct another
+object, but it's then auto-DESTROYed by perl rendering the object that
+used it corrupted. the solution is to make the newly created objects
+refer to the underlying object via magic attachment. only objects
+using objects that have DESTROY are effected. This concerns some of
+the methods accepting the custom APR::Pool object (not native pools
+like $r->pool). [Stas]
+Adjusted:
+- APR::Brigade: new
+- APR::Finfo: stat
+- APR::IpSubnet: new
+- APR::Table: copy, overlay, make
+- APR::ThreadMutex: new
+- APR::URI: parse
+- Apache::RequestUtil: new
+- APR::Pool: new
+- APR::BucketAlloc: new
+
+APR::Bucket::alloc_create moved to APR::BucketAlloc::new
+APR::Bucket::alloc_destroy moved to APR::BucketAlloc::destroy [Stas]
+
+prefork handlers optimisation: don't dup the handler struct unless
+this is a threaded-mpm [Stas]
+
+speed up the 'perl Makefile.PL' stage [Randy Kobes]:
+ - reduce the number of calls to build_config() of
+ Apache::Build within ModPerl::BuildMM
+ - cache the results of the calls to apxs_cflags, apxs_extra_cflags,
+ and apxs_extra_cppflags in Apache::Build
+ - in apxs of Apache::Build, return a cached result only when defined
+
+move ModPerl::Util::exit() into mod_perl.so, since it needs to work,
+even if ModPerl::Util wasn't loaded [Stas]
+
+
+
+=item 1.99_19 - December 23, 2004
+
+$r->hostname is now writable [Gozer]
+
+Static build with a Perl without ithreads and a non-threaded MPM
+would segfault on startup. Caused by a bug in perl's perl_shutdown()
+code. Fixed in Perl 5.8.2, so it's now a build requirement [Gozer]
+
+replace the added in 1.99_17 code on resetting/restoring PL_tainted,
+with explicit reset before and after each each callback. This solves a
+complicated tainting issues caused when perl exception object is
+thrown. rgs suggested that it should be safe, similar to perl's own
+pp_nextstate which says: /* Each statement is presumed innocent */
+[Stas]
+
+New configuration directives: [Gozer]
+ - PerlConfigRequire
+ Just like PerlRequire, but _always_ triggers an immediate
+ interpreter startup
+ - PerlPostConfigRequire
+ A delayed form of PerlRequire, that waits until the post_config
+ phase before require'ing files
+
+fix a warning in Apache::Status [John Williams <williams tni.com>]
+
+Ignore Apache-Test/META.yml in distribution tarballs until PAUSE
+is capable of handling multiple META.yml files in one distro [Gozer]
+
+modperl_exports.c now wraps all exported functions in a #ifndef
+function_name wrapper to help in weeding out functions that only make
+sense for certain Perl configurations (perlio, threads) (which also
+fixes static build against perlio-disabled perls, like 5.6.x) [Gozer]
+
+for make test, skip configuring fastcgi if it's found in the global
+httpd.conf, as it causes crashes in the test suite [Stas]
+
+fix Makefile.PL arguments parser to support more than one MP_foo
+option on the same line (including .makepl_args.mod_perl2 file) [Stas]
+
+fix compilation issues in ModPerl::Util::current_perl_id (on some
+builds newSVpvf can't be resolved but Perl_newSVpvf works just
+fine). [Stas, Markus Wichitill <mawic@gmx.de>]
+
+fix APR::Error::str to return a lexical variable, rather than a
+string. This function is called by SvTRUE in modperl_errsv() via
+overload and on win32 (and randomly on linux) causes crashes via:
+"Attempt to free temp prematurely" warning, where this 'temp' is the
+string returned by this function. Making it a lexical variable before
+returning it, resolves the problem. [Steve Hay]
+
+fix META.yaml s/private/no_index/ (to hide the bundled Apache-Test
+from PAUSE indexer) [Randy Kobes]
+
+
+
+=item 1.99_18 - December 12, 2004
+
+Fix x86_64 warnings in modperl_restart_count_*, due to casting between
+integers and pointer types [Joe Orton]
+
+open_logs and post_config handlers require the Apache::OK return code
+or the server aborts, so we need to log an error in case the handler
+didn't fail but returned something different from Apache::OK [Stas]
+
+new function ModPerl::Util::current_perl_id() which returns something
+like (.e.g 0x92ac760) (aTHX) under threaded mpm and 0 under
+non-threaded perl (0x0). Useful for debugging modperl under threaded
+perls. [Stas]
+
+make sure that modperl's internal post_config callback, which amongst
+other things, cloning perl interpreters is running as
+modperl_hook_post_config_last APR_HOOK_REALLY_LAST, which ensures that
+user's post_config callbacks are run before the cloning. now the code
+from config phase's startup.pl can be safely moved to the post_config
+phase's equivalent. [Stas]
+
+Further sync with libapr constants changes: [Stas]
+- the constants
+ APR::(READ|WRITE|CREATE|APPEND|TRUNCATE|BINARY|EXCL|BUFFERED|DELONCLOSE)
+ now have a prefix APR::FOPEN_ and moved group s/filemode/fopen/
+- constants from the fileprot group moved to the fprot group and the
+ prefix has changed: from APR::FILEPROT_ to APR::FPROT_
+- this also fixes the import of APR_EXCL as an error constant
+
+$r->print() and tied print() now return 0E0 (zero but true) when the
+call was successful but for zero bytes. [Geoffrey Young]
+
+a new function Apache::ServerUtil::server_shutdown_cleanup_register to
+register cleanups to be run at server shutdown. [Stas]
+
+$bb->cleanup is no more segfaulting (was segfaulting due to a broken
+prototype in APR, and consequently invalid XS glue code) [Randy Kobes,
+Stas]
+
+make sure that ABSPERLRUN and ABSPERLRUN are defined in
+src/modules/perl/Makefile (needed by win32 build) [Stas]
+
+For static builds, mod_perl header files were being installed
+into apache's source tree instead of where apache installed it's
+own headers [Gozer]
+
+modperl_threads_started() wasn't working under static worker build,
+due to MP_threads_started static variable not being reset on
+restart. Now resetting it. [Stas]
+
+@INC shrinking efforts: [Stas]
+1) when adding $ServerRoot don't add the trailing / (as it ends up
+twice when added by A-T w/o trailing /)
+2) add $ServerRoot/lib/perl only if it actually exists
+
+For static builds, we now run 'make clean' in httpd's source
+tree before running ./configure if the source tree has been
+configured before [Gozer]
+
+Apache::SizeLimit ported [Perrin Harkins <perrin elem.com>]
+
+create a new subpool modperl_server_user_pool (from
+modperl_server_pool), which is used internally by
+Apache::ServerUtil::server_restart_register. This ensures that
+user-registered cleanups are run *before* perl's internals cleanups
+are run. (previously there was a problem with non-threaded perls which
+were segfaulting on user cleanups, since perl was already gone by that
+time). [Stas]
+
+Starting from ExtUtils::MakeMaker 6.22 it no longer generates
+pm_to_blib target, but pm_to_blib.ts, so needed to fix the glue_pod
+target, so install will work correctly [Stas]
+
+Apache::RequestUtil : $r->child_terminate() implemented for
+non-threaded MPMs. [Gozer]
+
+new API Apache::ServerUtil::restart_count() which can be used to tell
+whether the server is starting/restarting/gracefully
+restarting/etc. Based on this feature implement
+$Apache::Server::Starting and $Apache::Server::ReStarting in
+Apache::compat [Stas]
+
+Apache::Resource ported to mp2 [Stas]
+
+If none of MP_APXS, MP_AP_PREFIX and MP_USE_STATIC were specified when
+configuring Makefile.PL, we now prompt for APXS path first and only if
+that fails ask for MP_AP_PREFIX. This is a requirement to get 'make
+test' find httpd. [Stas]
+
+Dynamically prompt and add MP_INST_APACHE2=1 when installing on
+systems with mod_perl 1 preinstalled. [Stas]
+
+fix the logging call in RegistryCooker [Lars Eggert <lars.eggert
+netlab.nec.de>]
+
+fix $r->filename in Apache::compat to update the finfo struct (which
+is how it worked in mp1) [Stas]
+
+enclose all occurences of eval_* with ENTER;SAVETMPS;
+... FREETMPS;LEAVE; previously things just happened to work, due to
+external scopes which was not very reliable and some change could
+introduce obsure bugs. [Stas]
+
+in case a native apache response filter is configured outside the
+<Location> block with PerlSet*Filter directive, make sure that
+mod_perl doesn't try to add it as connection filter (previously was
+logging an error like: [error] a content filter was added without a
+request: includes) [Stas]
+
+replace the slow implementation of anon handlers using B::Deparse,
+with per-interpreter cache of compiled CODE refs (sort of emulating
+named subroutines for anonymous handlers) [Stas].
+
+avoid segfaults when a bogus $r object is used [Stas]
+
+Remove magicness of PerlLoadModule and implement Apache::Module::add()
+for modules that implement their own configuration directives [Gozer]
+
+Apache::Connection::remote_ip is now settable (needed to set the
+remote_ip record based on proxy's X-Forwarded-For header) [Stas]
+
+Fix Modperl::Util::unload_package() [Gozer]
+ - Mistakenly skipping small entries of size 2 and less
+ - Leave entries from other packages alone
+
+$filter->remove now works with native (non-modperl) filters + test
+[Torsten Förtsch <torsten.foertsch gmx.net>]
+
+
+
+=item 1.99_17 - October 22, 2004
+
+Implement Apache->unescape_url_info in Apache::compat and drop it
+from the official API for CGI::Util::unescape() as a suggested
+replacement [Gozer]
+
+fix xs_generate to croak on duplicate entries in xs/maps files
+[Christian Krause <chkr plauener.de>]
+
+Workaround a possible bug in Perl_load_module() [Gozer]
+
+Fix a problem building with non-GNU make (can't make target dynamic
+in xs/APR/aprext) [Gozer]
+
+escape HTML in dumped variables by Apache::Status [Markus Wichitill
+<mawic@gmx.de>]
+
+$r->document_root can now be changed when safe to do so [Gozer]
+
+APR::Bucket->new now requires an APR::BucketAlloc as its first argument.
+New subs added: APR::Bucket::setaside, APR::Bucket::alloc_create,
+APR::Bucket::alloc_destroy, APR::Brigade::bucket_alloc. [joes]
+
+reimplement APR::Pool life-scope handling, (the previous
+implementation had problems) [joes]
+
+make sure that Apache::Filter::read, APR::Socket::recv,
+Apache::RequestIO::read, APR::Brigade::flatten, and APR::Bucket::read
+all return tainted data under -T [Stas]
+
+tag the custom pools created by mod_perl for easier pools debug [Joe
+Orton]
+
+fix a bug in non-ithreaded-perl implementation where the cached
+compiled CODE refs of httpd.conf-inlined one-liner handlers like:
+PerlFixupHandler 'sub { use Apache::Const qw(DECLINED); DECLINED }'
+didn't have the reference count right. [Stas]
+
+per-server PerlSetEnv and PerlPassEnv values are properly added
+to %ENV when only a per-directory handler is configured.
+[Geoffrey Young]
+
+resolve several 'Use of uninitialized value in...' warnings in
+Apache::Status [Stas].
+
+make install and static build now correctly installs mod_perl as
+well as the statically built apache [Gozer]
+
+if some code changes the current interpreter's tainted state to on,
+the return value from the handler callback will be tainted, and we
+fail to deal with that. So revert to coercing any return value, but
+undef (a special case for exit()). to IV, so that tainted values are
+handled correctly as well. [Stas]
+
+make sure that each handler callback starts with a pristine
+tainted-ness state, so that previous callback calls won't affect the
+consequent ones. Without this change any handler triggering eval or
+another function call, that checks TAINT_PROPER, will crash mod_perl
+with: "Insecure dependency in eval while running setgid. Callback
+called exit." farewell message [Stas]
+
+make sure that 'make distclean' cleans all the autogenerated files
+[Stas]
+
+$r->log_reason has been ported and moved out of Apache::compat
+[Gozer]
+
+APR::OS::thread_current renamed APR::OS::current_thread_id and
+now returns the actual thread_id instead of an object that
+needed to be dereferenced to get at the thread_id [Gozer]
+
+change a bunch of the APR:: constants to have a better prefix
+(APR::FILETYPE_* and APR::FILEPROT_). libapr will be changed soon too
+[Stas]
+
+Generate modperl_exports.c for static builds to prevent the
+linker from stripping needed but unused symbols [Gozer]
+
+Add .libs/ as part of the library search path when building
+against httpd's source tree [Gozer]
+
+In the static build, run make in httpd's srclib/ early to have
+generated files present at mod_perl configure time [Gozer]
+
+When searching for ap(r|u)-config in httpd's source tree, search
+into srclib/apr-util as well as srclib/apr [Gozer]
+
+Remove APR::Finfo::pool as it has no use to us [Stas]
+
+get PerlSetVar and PerlAddVar multi-level merges to (finally) work
+properly. [Rici Lake <rici ricilake.net>]
+
+MP_AP_BUILD configure option removed. Now implicit when MP_USE_STATIC
+is specified [Gozer]
+
+Apache::Module $mod->version() and $mod->minor_version() renamed
+to $mod->ap_api_major_version() and $mod->ap_api_minor_version
+for clarity [Gozer]
+
+Apache::Log changes: [Stas]
+ - moved to compat: Apache::warn, Apache->warn, Apache::Server->warn,
+ Apache::Server::warn
+ - re-enabled $r->warn
+ - removed support for Apache::ServerRec->warn
+ (Apache::ServerRec::warn is still there)
+
+Apache::Directive conftree() changed from class method to
+regular subroutine [Gozer]
+
+Apache::Module top_module() and get_config() as class methods
+added to Apache::compat for backwards compatibility [Gozer]
+
+Apache::Module top_module() and get_config() changed from class
+methods to regular subroutines [Gozer]
+
+Added Apache::CmdParms::add_config() to work around a memory
+leak discovered with <Perl> sections in .htaccess files [Gozer]
+
+Added ModPerl::Util::unload_package() to remove a loaded package
+as thoroughly as possible by clearing it's stash. [Gozer]
+
+fix Apache->request($r) to be set-able even w/: PerlOptions
+-GlobalRequest [Stas]
+
+Add Apache::Reload->unregister_module() to explicitely remove a
+module from Apache::Reload's monitoring list [Gozer]
+
+introduce a custom modperl error message for failing filter handlers
+(previously 'unknown error' coming from rc=500 was logged) [Stas]
+
+Fix Apache::Log methods/functions to log into the vhost's error_log
+file (if there is one). ( $s->log->*, $s->log_error, $s->log_serror,
+Apache::ServerRec::warn, etc.). Apache::ServerRec can now export its
+warn function to override CORE::warn [Stas]
+
+Fix $s->log->*, $s->log_error and $s->log_serror to again log into the
+vhost's error_log file (if there is one). [Stas]
+
+$s->log->warn and other $s->log->foo are now logging to the right
+vhost server and not the global one. modperl_sv2server_rec was
+broken. [Stas]
+
+Fix a glue_pod make target bug, when .pm file doesn't exist,
+e.g. ThreadMutex.pm is not created on unless
+$apr_config->{HAS_THREADS} [Stas]
+
+Introduce APR::Socket::poll to poll a non-blocking socket [Ken Simpson
+<ksimpson@larch.mailchannels.com>]
+
+Fix the error message when the minimal required httpd version is not
+satisfied [Pratik <pratiknaik@gmail.com>]
+
+Fix interactive prompting at perl Makefile.PL, when no APXS or
+MP_AP_PREFIX were provided. now asking for an alternative location if
+the suggested choices weren't selected. [Stas]
+
+Added APR::URI->rpath method. Returns the path of an uri minus
+path_info, if any. [Gozer]
+
+moved Apache::current_callback() to ModPerl::Util::current_callback
+where it belongs [Gozer]
+
+modperl_perl_module_loaded() fixed to use %INC to determine if a module
+is loaded instead of checking for the existence of a stash [Gozer]
+
+fix the modperl build, where httpd has been built against separate
+installations of apr-util and apr, where apr-util has been installed
+with a different includedir to apr. [Joe Orton]
+
+$Apache::Server::SaveConfig is now $Apache::PerlSections::Save
+[Geoffrey Young]
+
+
+
+=item 1.99_16 - Aug 22, 2004
+
+Fix a compilation problem breaking 1.99_15 (sv_copypv was added in
+perl 5.7.3) [Jason Woodward <woodwardj@jaos.org>]
+
+Added $r->content_languages in Apache::RequestRec [Gozer]
+
+APR::Bucket: add delete() and destroy() methods [Stas]
+
+
+
+=item 1.99_15 - Aug 20, 2004
+
+replace the memory allocation for modperl filter handlers to use a
+temporary subpool of the ap_filter_t object. previously using perl's
+safemalloc had problems on win32 (randomly my_perl == NULL) [Stas]
+
+Disable Apache::HookRun::run_create_request -- it's already run
+internally by Apache::RequestRec->new [Stas]
+
+Update Apache::RequestRec->new() to initialize members of request_rec
+which were added some time ago (without it we were getting segfaults
+in the new pseudo_http test. [Stas]
+
+Apache::CmdParms->limited member replaced by is_method_limited()
+method [Gozer]
+
+Apache::Module changes [Gozer]
+- readwrite => readonly:
+ cmds, next, name, module_index, minor_version, version
+- removed: remove_module
+
+ensure that a sub-dir Apache-Test exists in the source distro (this is
+a requirement, since the test suite relies on the particular
+Apache-Test version distributed with the mod_perl source) [Stas]
+
+combine handler resolving failure error with the actual error, so
+there is only one logged entry [Stas]
+
+pod manpages are now glued to all .pm files for which .pod exists at
+'make install' phase [Stas]
+
+Apache::RequestIO::sendfile() now indicates which file it has failed
+to open on failure. [Stas]
+
+fix Apache::SubRequest's methods: lookup_file, lookup_uri,
+lookup_method_uri to default the last argument to
+r->proto_output_filters (no request filters for the subrequest) and
+not r->output_filters->next as it was before (one filter was getting
+skipped and the rest of the filters were applied *twice*). [Stas]
+
+Apache::CmdParms changes [Gozer]
+- readwrite => readonly:
+ override, limited, directive, pool, temp_pool, server, path,
+ cmd, context, err_directive
+
+- removed: limited_xmethods, xlimited, config_file, err_directive
+
+Fix a bug in APR::Bucket->new when a passed argument was of type
+PADTMP [Stas]
+
+Apache::Connection changes [Stas, "Fred Moyer" <fred /about/
+taperfriendlymusic.org>]
+- readwrite => readonly:
+
+ pool, base_server, local_addr, remote_addr, remote_ip, remote_host,
+ aborted, local_ip, local_host, id, conn_config, sbh, bucket_alloc
+
+- removed: logname
+
+Move check_cmd_context from Apache::Command to Apache::CmdParms.
+[Gozer]
+
+Add :context group of constants for check_cmd_context().
+NOT_IN_VIRTUALHOST, NOT_IN_LIMIT, NOT_IN_DIRECTORY, NOT_IN_LOCATION,
+NOT_IN_FILES, NOT_IN_DIR_LOC_FILE & GLOBAL_ONLY [Gozer]
+
+Removed Apache::Command method soak_end_container [Gozer]
+
+Removed Apache::Module methods (dynamic_load_handle and
+find_module_name) [Gozer]
+
+All Apache::Command methods are now read-only [Gozer]
+
+Removed Apache::Command methods (func and cmd_data) [Gozer]
+
+Removed Apache::Directive methods (data & walk_config) [Gozer]
+
+All Apache::Directive methods are now read-only [Gozer]
+
+Filters should not reset $@ if it was already set before
+invocation [Gozer]
+
+Apache::compat server_root_relative now correctly handles absolute
+paths like ap_server_root_relative does [Gozer]
+
+Fix a bug in <Perl> sections with multiple aliases in a
+virtualhost container. [Gozer]
+
+PerlModule, PerlRequire, Perl and <Perl> is now supported in
+.htaccess. They will run for each request. [Gozer]
+
+removed support for httpd 2.0.46. httpd 2.0.47 is now the minimum
+supported version. [Geoffrey Young]
+
+Static builds for httpd >= 2.0.51 available. With the new MP_AP_BUILD
+option, configure and compile an httpd with mod_perl statically linked
+in [Gozer]
+
+Apache::RequestRec methods changes [Stas]
+- readwrite => readonly:
+
+ connection, canonical_filename, header_only, main, next, prev,
+ pool, per_dir_config, request_config, proto_num, protocol,
+ request_time, server, the_request, unparsed_uri
+
+- removed:
+
+ remaining - this method is not needed if the deprecated
+ $r->client_block methods aren't used, (use $r->read
+ $r->instead)
+ canonical_filename - it's a private member
+
+The func Apache::SubProcess::spawn_proc_prog is now a method:
+$r->spawn_proc_prog [Stas]
+
+Apache::Process methods (pool, pconf and short_name) are now read-only
+[Stas]
+
+($r|$c|$s)->server_root_relative were removed. Now only an explicit
+and somewhat deprecated function API remains:
+Apache::ServerUtil::server_root_relative($pool, $path); it's too easy
+to cause memory leak with this method, and it's inefficient as it
+duplicates the return value, to avoid potential segfaults if the pool
+it was allocated from gets destroyed and the value is attempted to be
+used. Instead of this method use the equivalent:
+File::Spec->catfile(Apache::ServerUtil::server_root, $fname); [Stas]
+
+$r->psignature now lives in the package it belongs to:
+Apache::RequestUtil (previously lived in Apache::ServerUtil). [Stas]
+
+A few functions moved namespace from Apache:: to Apache::ServerUtil::
+(to make it easier to find the container of the function): [Stas]
+ - exists_config_define
+ - server_root
+ - get_server_built
+ - get_server_version
+
+fix an old outstanding bug in the APR::Table's TIE interface with
+each()/values() over tables with multi-values keys. Now the produced
+order is correct and consistent with keys(). Though, values() works
+correctly only with perl 5.8.x and higher. [Joe Schaefer]
+
+require Perl 5.6.1, 5.6.0 isn't supported for a long time, but we
+weren't aborting at the Makefile.PL stage [Stas]
+
+Apache::RequestUtil::method_register($s->process->pconf, 'FOO'); is
+now $s->method_register('FOO').
+Apache::RequestUtil::add_version_component($s->process->pconf, 'BAR/0.1');
+is now $s->add_version_component('BAR/0.1'). [Stas]
+
+Remove $Apache::Server::StrictPerlSections. Now, all <Perl>
+sections errors are fatal by default and cause server startup to
+abort on error. [Gozer]
+
+Fix ($r|$filter|$bucket)->read() functions to run the set magic logic,
+to handle cases when a passed buffer to fill is not a regular
+scalar. [Stas]
+
+Apache::ServerRec accessors changes: [Stas]
+- readonly accessors:
+
+ process, next, is_virtual, module_config, lookup_defaults and
+ addrs
+
+- readwrite accessors with the exception of threaded mpms, where the
+ accessors are writable only before the child_init phase (i.e. before
+ threads are spawned):
+
+ server_admin, server_hostname, port, error_fname, error_log,
+ loglevel, timeout, keep_alive_timeout, keep_alive_max, keep_alive,
+ names, wild_names, limit_req_line, limit_req_fieldsize,
+ limit_req_fields, and path
+
+supports a new type of struct accessor, which is just like read/write
+one, but doesn't allow write access starting at the ChildInit phase
+under threaded mpm (to avoid thread-safely issues) [Stas]
+
+In order to be consistent with Apache::RequestRec, Apache::Server is
+now Apache::ServerRec and all methods/functions from Apache::Server
+now live in Apache::ServerRec. [Stas]
+
+Use a context-specific Perl_load_module() instead of load_module(), to
+avoid the problem with 'load_module' symbol resolution on certain
+platforms, where for some reason it doesn't get resolved at compile
+time to Perl_load_module_nocontext [Stas]
+
+Make it possible to disable mod_perl for the base server, but enable
+it for the virtual hosts [Stas]
+
+Removed the deprecated path argument to $r->add_config() [Gozer]
+
+Created a META.yml for CPAN and friends, including Apache-Test as
+a private resource to keep CPAN from installing mod_perl when a
+user just wants Apache::Test [Gozer]
+
+Moving HTTP specific functions get_status_line, method_register from
+Apache:: to Apache::RequestUtil:: to match their container [Stas]
+
+Adjust the list of mod_perl header files installed into the Apache2
+include/ directory, made necessary from the renaming and refactoring
+arising from the decoupling of APR and APR::* from mod_perl.so.
+Also include modperl_apr_perlio.h under xs/APR/PerlIO/ in
+the list of such files installed [Stas, Randy Kobes]
+
+$r->read()/READ now throw exceptions [Stas]
+
+$r->rflush now returns nothing (was always returning APR::SUCCESS
+before) [Stas]
+
+bug reports generating code: [Stas]
+- add (apr|apu)-config linking info
+- show the full path to the config file used to get the data for the
+ report
+
+The APR and APR::* family of modules can now be used without having
+to load mod_perl.so. On *nix, this is done by compiling the needed
+functions from the appropriate sources used to build mod_perl.so
+into APR.so, and then arranging for APR::* to 'use APR ()'. On Win32,
+a static library of needed functions is built, and APR/APR::*
+then link into this library [Stas, Joe Schaefer, Randy Kobes]
+
+APR::RequestIO::sendfile() now flushes any buffered output before
+sending the file contents out. If the return status is not checked and
+an error happens it'll throw an exception. Fix offset handling. [Stas]
+
+Registry: remove the misleading prefix "$$: $class:" in the logged
+error message, since not only registry errors will get logged if $@ is
+set [Stas]
+
+change t/REPORT to suggest to post bug reports to the modperl users
+list, to be consistent with the documentation [Stas]
+
+amd64 fixes [Joe Schaefer <joe+gmane@sunstarsys.com>]
+ - use IV insteaf of int where a pointer is used
+ - mpxs_APR__Bucket_new needs to use apr_size_t/off_set_t types
+
+APR::Socket::recv() now returns the length of the read data [Stas]
+
+APR::Bucket's read() returns "" instead of undef when there is no data
+to read. [Stas]
+
+fix a bug in Registry handlers, where the same error was logged twice
+and potentially a wrong error code returned [Stas]
+
+Apache::RequestIO: print(), printf(), puts(), write(), rflush() throw
+an exception on failure [Stas]
+
+Apache::SubRequest: run() throw an exception on failure [Stas]
+
+Apache::Filter: [Stas]
+ - remove unneeded methods: remove_input_filter() and
+ remove_output_filter(), fputs()
+ - frec() accessor is made read-only
+ - fflush(), get_brigade() and pass_brigade() now throw exceptions if
+ called in the void context
+ - read, print() and puts() throw an exception on failure
+
+Apache::FilterRec: [Stas]
+ - remove the next() accessor since it's not used by Apache at the
+ moment
+ - name() is made read-only
+
+APR::URI: [Stas]
+ - removed accessors
+ o is_initialized() (internal apr_uri flag)
+ o dns_looked_up() and dns_resolved() (they are not
+ used by apache/apr)
+ - all remaining accessors now accept undef value, which unsets the
+ field
+
+Extended WrapXS code to support a new type of accessor: char * which
+accepts undef to set the C pointer to NULL and as such unset the
+member of the struct. [Stas]
+
+Exception error messages now include the error id along with the error
+message (as they did in first place). [Stas]
+
+$r->finfo now accepts APR::Finfo object as an optional
+argument. [Stas]
+
+APR::Finfo [Stas]
+ - change stat() to return finfo
+ - make all field accessors readonly
+
+ARP::password_validate is now ARP::Util::password_validate [Stas]
+
+APR::IpSubnet::new() now throws APR::Error exception (not returning
+rc) [Stas]
+
+rename package APR::NetLib -> APR::IpSubnet to match the class name
+[Stas]
+
+APR::BucketType: [Stas]
+ - name is readonly
+
+APR::Brigade [Stas]
+ - destroy() now throws APR::Error exception (not returning rc)
+ - rename empty => is_empty
+ - added the method cleanup()
+ - flatten() now returns the number of bytes read (and passed the
+ buffer by the argument) and throws APR::Error exception
+
+APR::Bucket: [Stas]
+ - read() now returns the length of the read data and throws
+ APR::Error exception (not returning rc). The returned scalar is
+ now TAINTED.
+ - type->name now has a module APR::BucketType
+ - type(), length(), start(), data() are now all readonly
+ - new() fix a bug in offset handling
+
+
+
+=item 1.99_14 - May 21, 2004
+
+APR::SockAddr::port() accessor is now read-only [Stas]
+
+APR::Pool now has destroy() and clear() available [Stas]
+
+now logging the errors happening in pool cleanup callbacks [Stas]
+
+use the new Apache-Test attribute -minclient in the test suites. Now
+along with the default maxclients = minclients+1, we no longer should
+get 'server reached MaxClients setting' errors. [Stas]
+
+new API for APR::Socket recv() and send() + updated tests [Stas]
+
+add infrastructure for new ModPerl::Const constants and the first
+constant ModPerl::EXIT. [Stas]
+
+re-implement ModPerl::Util::exit to use exception objects, so it's
+possible to detect exit called in eval context and call it again
+outside the eval context. [Stas]
+
+add the perl interface for the new exception handling code (mod_perl,
+apache and apr methods will now throw exceptions with $@ being an
+object). New class APR::Error was added, to handle the exception
+objects with overload methods. Also added confess and croak
+equivalents of Carp's methods, since at the moment the Carp's ones
+don't work as is. The following perl and C methods have been renamed:
+ modperl_apr_strerror => modperl_error_strerror
+ APR::strerror => APR::Error::strerr
+[Stas]
+
+set the 'error-notes' table to the error message on
+HTTP_INTERNAL_SERVER_ERROR [Stas]
+
+fix the apxs build function to not handle empty lookups as errors
+[Randy Kobes, Steve Hay]
+
+fix type casting problems in the io functions [Stas]
+
+add support for libgtop 2.5.0+ (maintenance mode) [Stas]
+
+APR::Socket::timeout_set now croaks on failure [Stas]
+
+significantly speedup the startup of threaded mpm test suite, by
+configuring only the minimal number of perl interpreters to start
+[Stas]
+
+make APR::Socket::opt_(set|get) working (and change the previous
+behavior) [Stas]
+
+make sure that our protocol module tests that interact with the socket
+use a blocking read [Joe Orton]
+
+Use a better approach to figure out whether we need to strip perl's
+LargeFilesSource flag, by checking whether libapr was compiled with
+-D_FILE_OFFSET_BITS=64 or not. Checking for APR_HAS_LARGE_FILES is
+useless since it doesn't tell whether 32 vs 64 bits off_t and similar
+types are used [Joe Orton]
+
+'SetHandler perl-script' no longer grabs any newly encountered END
+blocks, and removes them from PL_endav, but only if they are
+explicitly registered via ModPerl::Global::special_list_register(END
+=> $package_name) (this is a new function). It's now possible to have
+a complete control of when END blocks are run from the user space, not
+only in the registry handlers [Stas]
+
+END blocks encountered by child processes and not hijacked by
+ModPerl::Global::special_list_register() are now executed at the
+server shutdown (previously they weren't executed at all). [Stas]
+
+Added test to ensure <Perl> sections can have things like %Location
+tied [Gozer]
+
+Fix the installation on Win32 so that an appropriate Apache2
+subdirectory under the Perl tree is used when MP_INST_APACHE2 is
+specified [Randy Kobes]
+
+Fix a redefined warning in Apache::Status [Stas]
+
+Fix Apache::Status, to lookup the Apache::Request version without
+loading it. Only if a suitable (2.x) version is found -- load and use
+it. Previously loading the 1.x version was affecting Apache::compat.
+[Stas]
+
+Fix a bug in special blocks handling (like END), which until now was
+dropping on the floor all blocks but the last one (mainly affecting
+registry handlers). [Stas]
+
+The filter streaming API print() function, now correctly handles a
+binary data [Stas]
+
+Fix Registry handlers, not to lose the execution errors, when they
+include END blocks [Stas]
+
+
+
+=item 1.99_13 - March 8, 2004
+
+respect $ENV{APACHE_TEST_STARTUP_TIMEOUT} settings if any [Stas]
+
+Added tests for issuing subrequests from filters [Geoffrey Young]
+
+Updated to the new Apache License Version 2.0 [Gozer]
+
+Drop the support for making GATEWAY_INTERFACE special. It's not needed
+as $ENV{MOD_PERL}, available in both mod_perl generations, should be
+used to test whether the code is running under mod_perl. [Stas]
+
+Handle correctly the situation when response HTTP headers are printed
+from the handler and the response body starts with \000, which is the
+case with some images like .ico. [Stas]
+
+Apache::PerlSections->dump() and store(filename) [Gozer]
+
+expose $c->keepalive related constants and $c->keepalives counter
+[Stas]
+
+Perl handlers are now guaranteed to run before core C handlers for
+all request phases. [Geoffrey Young]
+
+Fix the STDIN/OUT overriding process to handle gracefully cases, when
+either or both are closed/bogus (the problem was only with useperlio
+enabled perl) [Stas]
+
+copy apr_table_compress logic from later httpd versions in case mod_perl
+is built against 2.0.46, as mod_perl now requires it internally. users
+should be aware that 2.0.47 may become the oldest supported httpd version
+in the near future. [Geoffrey Young]
+
+Fix the corruption of the httpd process argv[0], caused by $0
+manipulating [Stas]
+
+ModPerl::MethodLookup::lookup_method now handles sub-classed objects
+[Stas]
+
+standard %ENV population with CGI variables and contents of the
+subprocess_env table (such as SetEnv and PassEnv) has been delayed
+until the last possible moment before content-generation runs.
+PerlSetEnv and PerlPassEnv are each an exception to this and are
+placed in both %ENV and the subprocess_env table immediately,
+regardless of the current [+-]SetupEnv setting.
+[Geoffrey Young]
+
+fix PerlAddVar configuration merging [Geoffrey Young]
+
+Anonymous subs are now supported in push_handlers, set_handlers,
+add_input_filter, etc. A fast cached cv is used with non-ithreaded
+perl. A slower deparse/eval approach (via B::Deparse) is used with
+ithreads enabled perls. Further optimizations are planned for the
+latter case. [Stas]
+
+ht_time w/o the pool is now available only via override/restore compat
+API. format_time, has been renamed back to ht_time, and the default
+values for fmt, time and gmt are now supported. [Stas]
+
+it's now possible to push new handlers into the same phase that is
+running at the moment [Stas].
+
+when $r->handler($new_handler) is called from a response phase, it now
+checks that the response handler type is not switched (e.g. from
+'modperl' to 'perl-script') from the currently used one [Stas]
+
+Since Apache::SubProcess is now part of the mp2 API, add
+$r->cleanup_for_exec as a noop in Apache::compat. That function is no
+longer needed in Apache2. [Stas]
+
+When 'perl Makefile.PL PREFIX=/foo/bar' is used and mod_perl 1 is
+found, but at different prefix no longer require
+MP_INST_APACHE2=1. [Stas]
+
+modperl_mgv_resolve now croaks when a module scheduled for autoloading
+fails to load. AutoLoaded modules shouldn't silently fail. [Stas]
+
+Perl(Input|Output)FilterHandler handlers are now always AutoLoaded, as
+if '+' prefix was used. This must be performed to get the access to
+filter attributes long before the filter itself is executed. [Stas]
+
+APR/Pool.xs has been reimplemented. The problem with the previous
+implementation is that a dead perl pool object could hijack a newly
+created pool, which didn't belong to that object, but which happened
+to be allocated at the same memory location. The problem is that
+apr_pool_user_data_set/get has no mechanism to check whether the pool
+has changed since it was last assigned to (it does but only in the
+debug mode). It really needs some signature mechanism which can be
+verified that the pool is still the same pool. Since apr_pool doesn't
+have this feature, the reference counting has been reimplemented using
+a plain sv reference. Several new (mainly hijacking) tests which badly
+fail with the previous impelementation have been added. [Stas]
+
+fix calling $r->subprocess_env() in a void context so that it only
+populates %ENV if also called with no arguments. also, make sure it
+can be called more than once and still populate %ENV.
+[Geoffrey Young]
+
+add APR::Brigade::pool() to allow access to the pool associated with
+the brigade [Geoffrey Young]
+
+make 't/TEST -startup_timeout secs' working (previously user's value
+was ignored) [Stas]
+
+ModPerl::Registry and friends now support non-parsed headers scripts,
+whose filename =~ /^nph-/, identically to mod_cgi. + test [Stas]
+
+implement APR::Brigade::length() and APR::Brigade::flatten() (the
+latter implements a wrapper for apr_brigade_flatten, but also includes
+an emulation of apr_brigade_pflatten) as [Geoffrey Young]
+
+($r|$s)->add_config() now die if failed (previously returned the
+error) [Stas]
+
+fix context problems in <perl> sections and
+PerlModule/PerlLoadModule/PerlRequre under threaded mpms w/
+PerlOptions +Parent/+Clone in Vhosts + TestVhost::config test. [Stas]
+
+Implemented Apache::get_server_version and Apache::get_server_built
+as constant subroutines [Geoffrey Young]
+
+Moved some functions out of the Apache:: namespace:
+ Apache::unescape_url() is now Apache::URI::unescape_url()
+ Apache::log_pid() is now Apache::Log::log_pid()
+ Apache::LOG_MARK() is now Apache::Log::LOG_MARK()
+[Geoffrey Young]
+
+if MP_AP_PREFIX is used apxs and apr-config from the apache build tree
+won't work, so it can't co-exist with MP_APXS and MP_APR_CONFIG build
+options - ensure that this doesn't happen. [Stas]
+
+server_root_relative() now requires either a valid pool or an $r, $s,
+or $c object as a first argument. also, the returned result is a
+copy, protecting against cases where the pool would go out of scope
+before the result. [Geoffrey Young]
+
+Check the success of sysopen in tmpfile() in compat [Geoffrey Young]
+
+make sure DynaLoader is loaded before XSLoader, not only with perl
+5.6.1, but always because of the issues with <Perl> sections are
+loaded from +Parent vhost [Stas]
+
+added ($r|$s)->is_perl_option_enabled($option_name), to test for
+PerlOptions + tests [Stas]
+
+On Solaris add a workaround for xs/APR/APR/Makefile.PL to build
+APR.so, correctly linked against apr and apr-util libs, by addding the
+missing -R paths corresponding to -L flags. EU::MM was adding them via
+LD_RUN_PATH instead of using -R, but since perl's lddflags may have -R
+it overrides LD_RUN_PATH. So explicitly add anything that may go into
+LD_RUN_PATH via -R. Also make sure that -R coming from Apache will
+appear first. [Brad Lanam <bll@gentoo.com>]
+
+'make dist' now generates and picks Apache-Test/META.yml which was
+always reported missing, as it was included in Apache-Test/MANIFEST
+[Stas]
+
+fix the $r->read function to return undef on failure similar to the
+core perl function and make $! available for those who test for read()
+failures. [Stas]
+
+Make sure that pnotes are destroyed after PerlCleanup handlers are
+finished and not before + test. [Stas]
+
+
+
+=item 1.99_12 - December 22, 2003
+
+Restore a proper behavior of all Registry handlers, but PerlRun, not
+to reset %INC to forget any .pl files required during the script's
+execution. [Stas]
+
+<Perl> are now evaluating code into one distinct namespace per
+container, similar to ModPerl::Registry scripts. [Philippe M. Chiasson]
+
+Fix ModPerl::MM::WriteMakefile to use the MODPERL_CCOPTS entry from
+Apache::BuildConfig, as it contains some flags added by mod_perl,
+which aren't in perl_ccopts and ap_ccopts. [Stas]
+
+Add the implementation of Apache::Connection::local_addr and
+Apache::Connection::remote_addr to the Apache::compat overridable
+functions. [Stas]
+
+Apache::compat's implementation of APR::URI::unparse,
+Apache::RequestRec::finfo and Apache::RequestRec::notes is now
+overridable and not enabled by default. [Stas]
+
+Apache::compat no longer enables functions which collide with mp2 API
+by default. It provides two new functions: override_mp2_api and
+restore_mp2_api to override and restore the original mp2 API. [Stas]
+
+For Win32, add a .bat extension to candidates for the apxs and
+apr-config utilities used in Apache::Build, so that the -x file
+test can potentially succeed [Randy Kobes]
+
+Plug a memory leak with 'perl-script' not cleaning up the temp vars
+created during the override of STDIN/STDOUT to use the :Apache IO
+layer [Stas]
+
+libgtop config (needed for enabling MOD_PERL_TRACE=m) is now searched
+using the gnome packaging tools if available (pkg-config for gnome-2.x
+and gnome-config for gnome-1.x) [Stas]
+
+Prevent a problem where an autovivified package (stash) prevents from
+modperl_mgv to load the file with that package (until now it was
+checking whether the stash existed already and skipped the loading if
+that was the case). Now checking %INC and attempting to load the
+module. Reporting the failure only if the module has failed to load
+and the stash is not defined (so that it's possible to autovivify
+packages without loading them from an external file). [Stas]
+
+MaxClients is now overridable from the t/TEST -maxclients command line
+option (it was hardcoded before). [Stas]
+
+Postpone the allocation of the wbucket in filters till the moment it's
+needed (if at all). Since non-streaming filters aren't going to use
+that buffer, it's a waste to allocate/free it. [Stas]
+
+Extend the autogenerated bug report to include information about
+installed modules of special interest (which may aid in understanding
+the bug report), such as CGI.pm, Apache::Request, LWP, etc. [Stas]
+
+As the test suite keeps on growing, it takes longer time to
+startup. Change the main test suite timeout to 180 secs for threaded
+mpms and 120 secs for non-threaded ones. [Stas]
+
+use plain malloc/free to allocate filter structs, since they could be
+invoked hundreds of times during a single request, causing huge memory
+demands if the memory is allocated from the pool, which gets destroyed
+only at the end of a request. [Stas]
+
+Fix a compilation error in APX.xs when MP_HAVE_APR_LIBS is not defined
+[Fred Moyer <fred@taperfriendlymusic.org>]
+
+fix a memory leak when $filter->ctx is used [Stas]
+
+fix buglet on Win32 (and potentially other non-Unix platforms)
+where not all files were being installed under a relative Apache2
+subdirectory when MP_INST_APACHE2 was specified [Randy Kobes].
+
+deprecated APR::SockAddr::port_get()/APR::SockAddr::port_set()
+replaced with direct access to the port record via
+APR::SockAddr::port(). [Geoffrey Young, Stas]
+
+deprecated APR::URI::default_port_for_scheme() replaced with
+APR::URI::port_of_scheme() [Geoffrey Young]
+
+deprecated APR::SockAddr::ip_set() and APR::NO_TIMEOUT removed.
+[Geoffrey Young]
+
+Apache::MPM->is_threaded() replaces Apache::MPM_IS_THREADED
+[Geoffrey Young]
+
+fix "PerlSetVar Foo 0" so that $r->dir_config('Foo') returns 0, not undef
+[Geoffrey Young]
+
+add Apache::MPM class, along with show() and query() class methods
+[Geoffrey Young]
+
+add :mpmq import tag to Apache::Const [Geoffrey Young]
+
+Fix ModPerl::Registry handlers family to modify $0 only for the
+duration of the handler, by localizing it [Stas]
+
+Fix :Apache perlio's STDOUT to be reentrant + modules/include_subreq
+test [Stas]
+
+fix slurp_filename to always open the file and not try to guess
+whether filename has been already opened, as there is no reliable way
+to accomplish that [Stas]
+
+Apache->can_stack_handlers is now in Apache::compat (mp2 always can
+stack handlers) [Stas]
+
+add access to $r->finfo() and related APR::Finfo methods,
+such as $r->finfo->size(), $r->finfo->mtime(), and
+$r->finfo->stat() [Geoffrey Young]
+
+add :filetype import tag to APR::Const [Geoffrey Young]
+
+<Perl> sections now properly set $0 to the name of the configuration
+file they are in. [Philippe M. Chiasson]
+
+Apache::Status: provide a workaround for Config::myconfig() which
+fails under threads with (5.8.0 < perl < 5.8.3) [Elizabeth Mattijsen
+<liz@dijkmat.nl>]
+
+Fix Apache::Status::handler to return 'Apache::OK' [Juanma Barranquero
+<lektu@terra.es>]
+
+<Perl> sections now properly set filename and line number information,
+making error messages report the correct location. [Philippe M. Chiasson]
+
+
+
+=item 1.99_11 - November 10, 2003
+
+add a build/win32_fetch_apxs script (called within the top-level
+Makefile.PL) to offer to fetch and install a Win32 development
+version of apxs and (apr|apu)-config [Randy Kobes]
+
+rewrite $r->read() and perlio read functions to use the same function,
+which completely satisfies the read request if possible, on the way
+getting rid of get_client_block and its supporting functions which
+have problems and will most likely will be removed from the httpd-API
+in the future. Directly manipulate bucket brigades instead. [Stas]
+
+Since Apache2.pm pops /foo/Apache2 dirs to the top of @INC, it now
+also takes care of keeping lib and blib dirs before the system dirs,
+so that previously installed libraries won't get loaded instead of the
+currently uninstalled libraries that are under test. [Stas]
+
+When 'make test' fails we now print the info on what to do next [Stas]
+
+At the end of 'make install' we now print the info how to proceed with
+mod_perl and what to do in the case of post-install problems
+[Geoffrey Young]
+
+Adjust the source to properly work with 5.8.2's new algorithm of
+dynamic re-hashing of hashes on hash collision attack. [Nicholas Clark
+<nick@ccl4.org>, Stas]. Add a test that mounts such an attack so we
+can verify that we can survive this rehashing. [Scott A Crosby
+<scrosby@cs.rice.edu>, Nicholas Clark <nick@ccl4.org>, Tels
+<perl_dummy@bloodgate.com>, Mark Jason Dominus <mjd@plover.com>, Stas]
+
+Standardize the Apache::PerlSections package name to it's plural form for
+clarity and so that the pod gets glued in it's proper place.
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+return value from Perl callbacks are now passed directly to Apache
+without additional post-call manipulations (such as assuming HTTP_OK
+should really be OK). [Geoffrey Young]
+
+perl 5.8.1 w/ ithreads has a bug where it reports the wrong parent pid
+(as if the process was never forked), provide a local workaround (+ new
+test). [Rafael Garcia-Suarez <rgarciasuarez@free.fr>]
+
+overridden STD* streams now can be further overridden and will be
+properly restored, which allows functions like $r->internal_redirect
+work (+add tests) [Stas]
+
+implement perlio's getarg hook, which now allows duping STD* streams
+overloaded by modperl [Stas]
+
+Add PerlMapToStorageHandler [Geoffrey Young]
+
+callbacks are now expected to return a meaningful value
+(OK, SERVER_ERROR, etc) or return via an official API
+(exit, die, etc). relying on implicit returns from the
+last call evaluated by a subroutine may result in server
+errors. [Stas, Geoffrey Young]
+
+in the MP_MAINTAINER mode add the -Werror compilation flag when perl
+v5.6.2 or higher is used, so that we don't miss compilation
+warnings. [Stas]
+
+fix the Makefile.PL option parser to support overriding of certain
+build options, in addition to appending to them (.e.g. now MP_LIBNAME
+is overridable) [Andrew Wyllie <wyllie@dilex.net>]
+
+make sure that connection filters won't be inserted as request filters
+[Stas]
+
+Prevent the 'Use of uninitialized value.' warning when
+ModPerl::Util::exit is used. [Stas]
+
+To make the test-suite sandbox-friendly, which break when things try to
+run off /tmp, use t/logs as the location of the mod_cgid socket and
+TMPDIR env var [Haroon Rafique <haroon.rafique@utoronto.ca>]
+
+
+
+=item 1.99_10 - September 29, 2003
+
+added Apache::CRLF, Apache::CR, and Apache::LF to
+Apache::Const's :platform group [Geoffrey Young]
+
+make sure that the custom pools are destroyed only once and only when
+all references went out of scope [Stas]
+
+($r|$c)->add_(input|output)_filter(\&handler) now verify that the
+filter of the right kind is passed and will refuse to add a request
+filter as a connection filter and vice versa. The request filter
+handler is not required to have the FilterRequestHandler attribute as
+long as it doesn't have any other attributes. The connection filter
+handler is required to have the FilterConnectionHandler
+attribute. [Stas]
+
+fix tracing with (PerlTrace/MOD_PERL_TRACE) on win32 (the error_log
+filehandle was invalid after the open_logs phase) [Stas]
+
+fix a bug where %ENV vars set via subprocess_env persist across
+requests. (e.g. a Cookie incoming header which ends up in
+$ENV{HTTP_COOKIE} would persist to the next request which has no
+Cookie header at all). Now we unset all the %ENV vars set from
+subprocess_env. Improve and extend the tests to cover this bug. [Stas]
+
+it is invalid to return HTTP_INTERNAL_SERVER_ERROR or any other HTTP
+response code from modperl_wbucket_pass, therefore set the error code
+into r->status and return APR_SUCCESS. Until now response handler
+with messed up response headers, were causing no response what so ever
+to the client. LWP was assuming 500, and it was all fine, testing
+without LWP has immediately revealed that there was a problem in the
+handling of this case. [Stas]
+
+put the end to the 'Not a CODE reference' errors, instead provide an
+intelligent error message, hopefully telling which function can't be
+found. at the same time improve the tracing to include the pid/tid of
+the server that has encountered this problem, to make it easier to
+debug. [Stas]
+
+mod_perl handler must be duped for any mpm which runs within
+USE_ITHREAD. Until now there was a big problem with prefork mpm if
+any of its vhosts was using PerlOptions +(Parent|Clone) and happened
+to load handlers before the main server. When that was happening the
+main server will see that the handler was resolved (since it sees the
+handler struct from the vhost that loaded this module, instead of its
+own), which in fact it wasn't, causing the failure to run the handler
+with the infamous 'Not a CODE reference' error. [Stas]
+
+Make sure that the static mod_perl library is built after the dynamic
+(a requirement on win32) [Steve Hay <steve.hay@uk.radan.com>]
+
+Apache::Status now generates HTML 4.01 Strict (and in many cases, also
+ISO-HTML) compliant output. Also add a simple CSS to make the reports
+look nicer. [Ville Skyttä <ville.skytta@iki.fi>]
+
+APR::Pool::DESTROY implemented and tweaked to only
+destroy pools created via APR::Pool->new() [Geoffrey Young]
+
+$r->slurp_filename is now implemented in C. [Stas]
+
+remove support for httpd 2.0.45/apr 0.9.3 and lower.
+httpd 2.0.46 is now the minimum supported version.
+[Geoffrey Young]
+
+APR::PerlIO now accepts the pool object instead of a request/server
+objects, so it can be used anywhere, including outside mod_perl [Stas]
+
+when perl is built with perlio enabled (5.8+) the new PerlIO Apache
+layer is used, so now one can push layers onto STDIN, STDOUT handles
+e.g. binmode(STDOUT, ':utf8'); [Stas]
+
+add ap_table_compress() to APR::Table [Geoffrey Young]
+
+alter stacked handler interface so that mod_perl follows Apache
+as closely as possible with respect to VOID/RUN_FIRST/RUN_ALL
+handler types. now, for phases where OK ends the Apache
+call list (RUN_FIRST handlers, such as the PerlTransHandler),
+mod_perl follows suit and leaves some handlers uncalled.
+[Geoffrey Young]
+
+Apache::Build now tries to use the new APR_BINDIR query string to find
+the location of apr-config. [Stas]
+
+new package Apache::porting to make it easier to port mp1 code to mp2
+[Stas]
+
+new Apache::Build methods: mpm_name(), mpm_is_threaded(). use them in
+the top-level Makefile.PL to require 5.8.0/ithreads if mpm requires
+threads. [Stas]
+
+add the missing XS methods to ModPerl::MethodLookup, add support for
+mp1 methods that are no longer in the mod_perl 2.0 API. [Stas]
+
+mod_perl now refuses to build against threaded mpms (non-prefork)
+unless perl 5.8+ w/ithreads is used [Stas]
+
+don't try to read PERL_HASH_SEED env var, where apr_env_get is not
+available (apr < 0.9.3) [Stas]
+
+APR.so now can be loaded and used outside mod_perl (all the way back
+to httpd 2.0.36) [Stas]
+
+perl 5.8.1 randomizes the hash seed, because we precalculate the hash
+values of mgv elements the hash seed has to be the same across all
+perl interpreters. So mod_perl now intercepts cases where perl would
+have randomize it, do the seed randomization by itself and tell perl
+to use that value. [Stas]
+
+fix APR::PerlIO layer to pop itself if open() has failed. [Stas]
+
+move the definition of DEFINE='-DMP_HAVE_APR_LIBS' to the top level
+Makefile.PL, since it overrides MY::pasthru target which makes it
+impossible to define local DEFINE in subdirs. [Stas]
+
+make APR perl functions work outside mod_perl: several libraries
+weren't linked. Also LIBS needs to receive all libs in one
+string. [Stas]
+
+Apache::compat: $r->cgi_env, $r->cgi_var are now aliases to
+$r->subprocess_env [Stas]
+
+For Win32, generate .pdb files for debugging when built with
+MP_DEBUG. These will get installed into the same directory as
+the associated dll/so libs. As well, install mod_perl.lib
+into MP_AP_PREFIX/lib/ for use by 3rd party modules [Randy Kobes].
+
+Apache2.pm is now autogenerated and will adjust @INC to include
+Apache2/ subdirs only if built with MP_INST_APACHE2=1 [Stas]
+
+Change the default value for the argument 'readbytes' for
+ap_get_brigade(), from 0 to 8192. other than being useless, 0 always
+triggers an assert in httpd internal filters and 8192 is a good
+default. [Stas]
+
+Fix DynaLoader breakage when using DL_GLOBAL on OpenBSD
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+renamed the private modperl_module_config_get_obj function to
+modperl_module_config_create_obj, since the logic creates
+the object but doesn't dig it out if it already exists. then,
+moved logic from mpxs_Apache__Module_get_config into a new public
+C function that reused the old name, modperl_module_config_get_obj.
+while Apache::Module->get_config exists as a wrapper to return the
+object to Perl space, now C/XS folks can also access the object
+directly with the public function.
+[Geoffrey Young]
+
+Apache::Reload: add a new config variable:
+ReloadConstantRedefineWarnings to optionally shut off the constant sub
+redefine warnings [Stas]
+
+implement $parms->info. directive handlers should now be complete.
+[Geoffrey Young]
+
+MP_GTOP now works with modern GCC
+[Philippe M. Chiasson <gozer@cpan.org]
+
+add missing dependencies to Apache::PerlSections
+[Geoffrey Young]
+
+$r->get_client_block is bogus in httpd-2.0.45 (and ealier), as it
+can't handle EOS buckets arriving in the same bucket brigade with
+data. so rewrite ModPerl::Test::read_post to use an explicit read
+through all bucket brigades till it sees eos and then it stops. The
+code is longer but it works correctly. [Stas]
+
+an attempt to resolve the binary compatibility problem in
+PerlIOAPR_seek API when APR_HAS_LARGE_FILES=0 [Stas]
+
+perl 5.8.0 forgets to export PerlIOBase_noop_fail, causing problems on
+win32 and aix. reimplement this function locally to solve the
+problem. APR::PerlIO should now be useful on win32 and aix [Stas]
+
+implement DECLINE_CMD and DIR_MAGIC_TYPE constants
+[Geoffrey Young]
+
+allow init filter handlers to call other methods than just $f->ctx [Stas]
+
+Fix Apache::Reload to gracefully handle the case with empty Touchfiles
+[Dmitri Tikhonov <dmitri@netilla.com>]
+
+PerlRequire entried should be executed before PerlModule entries in
+VirtualHost containers, just like in the base server [Stas]
+
+
+
+=item 1.99_09 - April 28, 2003
+
+$filter->seen_eos() now accepts 1/0 to set/unset the flag so streaming
+filters can control the sending of EOS. [Stas]
+
+support systems where apr header files are installed separately from
+httpd header files ["Andres Salomon" <dilinger@voxel.net>]
+
+implement init filter handlers + tests [Stas]
+
+improving ModPerl::MethodLookup to:
+- handle more aliased perl XS functions
+- sort the methods map struct so one can use the autogenerated map as is
+- add lookup_module, tells which methods are defined by a given module
+- add lookup_object, tells which methods can be called on a given object
+- provide autoexported wrappers print_method, print_module and
+ print_object for easy deployment from the command line
+[Stas]
+
+add Perl glue for functions: APR::Socket::timeout_get
+APR::Socket::timeout_set [Stas]
+
+similar to SetEnv, upcase the env keys for PassEnv on platforms with
+caseless env (e.g. win32) [steve.sparling@ps.ge.com]
+
+Add a backcompat wrapper for $r->notes (mp2 supports only the
+APR::Table API) [Stas]
+
+Add a script mp2bug and a target 'make bugreport', so people can use
+bugreporting during the build and after modperl is installed. [Stas]
+
+Add a script mp2doc as a replacement for perldoc (due to 2.0 modules
+living under Apache2, which won't be looked at by perldoc). [Stas]
+
+Add a constant APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED and use it in
+tests [Stas]
+
+Require perl 5.8 or higher when building mod_perl on OSes requiring
+ithreads (e.g., win32), since 5.6.x ithreads aren't good. [Stas]
+
+MP_COMPAT_1X=0 now can be passed to Makefile.PL to disable
+mp1-back-compat compile-time features + adjust tests. [Stas]
+
+<SERVER_ROOT> and <SERVER_ROOT>/lib/perl are now added to @INC, just
+like mod_perl 1.0 with MP_COMPAT_1X=1 (currently enabled by
+default). [Stas]
+
+The Perl-5.8.0 crypt() workaround is now used only if 5.8.0 is used,
+since 5.8.1-tobe/5.9.0-tobe(blead-perl) won't compile with
+it. [Geoffrey Young]
+
+new directives PerlSetInputFilter and PerlSetOutputFilter, which are
+the same as SetInputFilter and SetOutputFilter respectively, but allow
+to insert non-mod_perl filters before, between or after mod_perl
+filters. + tests [Stas]
+
+improved filters debug tracing [Stas]
+
+implement $filter->remove (filter self-removal) + tests [Stas]
+
+remove the second-guessing code that was trying to guess the package
+name to load from the handler configuration (by stripping ::string and
+trying to load the package). fall back to using explicit PerlModule to
+load modules whose handler sub name is not called 'handler' + adjust
+tests. [Stas]
+
+set the magic taint flags before modules are required [Stas]
+
+make sure to set base server's mip before any of the
+PerlRequire/PerlModule directives are called, since they may add
+add_config(), which in turn runs Perl sections or PerlLoadModule,
+which may need the scfg->mip to be set. [Stas]
+
+ModPerl::MM is now ready to be used in Makefile.PL of 3rd party
+mod_perl modules [Stas and Geoff]
+
+fix a segfault caused by PerlModule in $s->add_config, due to setting
+the MP_init_done flag before init was done + add test [Stas]
+
+adjust the generated Makefile's to properly build on aix (tested on
+powerpc-ibm-aix5.1.0.0) [Stas]
+
+the build now automatically glues the .pod files to the respective .pm
+files, so one can use perldoc on .pm files to read the
+documentation. [Stas]
+
+provide a workaround for ExtUtils::MakeMaker::mv_all_methods, so
+ModPerl::BuildMM and ModPerl::MM can override EU::MM methods behind
+the scenes. [Stas]
+
+adding ModPerl::BuildMM, which is now used for building mod_perl.
+ModPerl::MM will be used for 3rd party modules. ModPerl::BuildMM
+reuses ModPerl::MM where possible. [Stas]
+
+drop the glue code for apr_generate_random_bytes, since it's not
+available on all platforms. [Stas]
+
+Since non-threaded mpms don't use tipools in mips, don't create and
+destroy them. [Stas]
+
+re-use the workaround for glibc/Perl-5.8.0 crypt() bug for the
+main/vhost base perl interpreters as well. This solves the problem for
+the buggy glibc on RH8.0. [Stas]
+
+send_cgi_header now turns the header parsing off and can send any data
+attached after the response headers as a response body. [Stas]
+
+move the check that print/printf/puts/write/etc are called in the
+response phase into the functions themselves so 1) we can print a more
+useful error message 2) this check is not always needed in
+modperl_wbucket_write, when called internally, so we save some cycles.
+[Stas]
+
+add checks that print/printf/puts/write/etc are called in the response
+phase. move the check into the functions themselves so we can print a
+more useful error message [Stas]
+
+'make install' now installs mod_perl*h files under httpd's include
+tree [Stas]
+
+When PerlOptions +ParseHeaders is an effect, the CGI headers parsing
+won't be done if any *mod_perl* handler before and including the
+response phase, sets $r->content_type. (similar behavior to mp1's
+send_http_header() [Stas]
+
+Registry: make sure that $r is not in the scope when the script is
+compiled [Stas]
+
+$Apache::Server::SaveConfig added. When set to a true value,
+will not clear the content of Apache::ReadConfig:: once <Perl >
+sections are processed. [Philippe M. Chiasson <gozer@cpan.org]
+
+Apache::compat: support 1.0's Apache->push_handlers,
+Apache->set_handlers and Apache->get_handlers [Stas]
+
+revamp the code handling output flushing and flush bucket
+sending. Namelly modperl_wbucket_flush and modperl_wbucket_pass now
+can be told to send a flush bucket by themselves, attaching it to the
+data bb they are already sending. This halfs the number of output
+filter invocations when the response handler flushes output via $| or
+rflush. adjust tests, which were counting the number of invocations.
+[Stas]
+
+move ModPerl::RegistryCooker to use a hash as object (similar to mp1),
+to make it easier to subclass. [Nathan Byrd <nathan@byrd.net>]
+
+$r->rflush has to flush internal modperl buffer before calling
+ap_rflush, so implement rflush, instead of autogenerating the xs code
+for it. [Stas]
+
+fix the input filters handling of DECLINED handlers (consume the data,
+on behalf of the handler) + tests [Stas]
+
+fix the code that autogenerates modperl_largefiles.h not to define
+macros matching m/^-/ (was a problem on aix-4.3.3) [Stas]
+
+$Apache::Server::StrictPerlSections added. When set to a true
+value, will abort server startup if there are syntax errors
+in <Perl > sections [Philippe M. Chiasson <gozer@cpan.org]
+
+Use Win32::GetShortPathName for Win32 to handle cases when
+the supplied MP_AP_PREFIX contains spaces. [Randy Kobes]
+
+Bump up ThreadsPerChild for mpm_winnt in httpd.conf, which seems
+to help avoid server startup problems when running the tests.
+[Randy Kobes]
+
+implement a new helper module ModPerl::MethodLookup to help figure out
+which module should be loaded when a certain method is reported to be
+missing. [Stas]
+
+fix a bug for apr < 0.9.3, where it segfaults in apr_uri_unparse, if
+hostname is set, but not the scheme. In case the hostname is defined
+but scheme is not Apache::compat will default to the 'http' scheme,
+whereas APR::URI::unparse provides no default [Stas]
+
+move $r->send_http_header implementation to Apache::compat. This
+allows the 1.0 code to run unmodified if $r->send_http_header is
+called before the response change. we already handle the check whether
+content_type was set, when deciding whether the headers are to be
+parsed inside modperl_wbucket_pass(). [Stas]
+
+fixes to Apache::compat. make $r->connection->auth_type interface
+with r->ap_auth_type. make both $r->connection->auth_type and
+$r->connection->user writable. [Geoffrey Young]
+
+Open up r->ap_auth_type, making it possible to write custom
+authen handlers that don't rely on Basic authentication or
+it's associated ap_* functions.
+[Geoffrey Young]
+
+add Apache::Bundle2 [Stas]
+
+Apache::Reload now supports the PerlPreConnectionHandler invocation
+mode, so connection filter and protocol modules can be automatically
+reloaded on change. [Stas]
+
+implement Apache::current_callback + $r->current_callback goes into
+Apache::compat, since now we have a way too many callbacks unrelated
+to $r [Stas]
+
+Add Apache::compat methods: $r->connection->auth_type and
+$r->connection->user (requires 'PerlOptions +GlobalRequest') + tests
+[Stas]
+
+Several issues resolved with parsing headers, including making work
+the handlers calling $r->content_type() and not sending raw headers,
+when the headers scanning is turned on. Lots of tests added to
+exercise different situations. [Stas]
+
+warn on using -T in ModPerl::Registry scripts when mod_perl is not
+running with -T [Stas]
+
+perl 5.7.3+ has a built-in ${^TAINT} to test whether it's running
+under -(T|t). Backport ${^TAINT} for mod_perl running under
+5.6.0-5.7.3, (what used to be $Apache::__T. $Apache::__T is available
+too, but deprecated. [Stas]
+
+add PerlChildExitHandler implementation [Stas]
+
+add PerlCleanupHandler implementation + test [Stas]
+
+die when Apache->request returns nothing ('PerlOptions -GlobalRequest'
+or 'SetHandler modperl') [Stas]
+
+New Apache::Directive methods: as_hash(), lookup() + tests + docs
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+Stacked handlers chain execution is now aborted when a handler returns
+something other than OK or DECLINED [Stas]
+
+make $filter->read() in input streaming filters, use the same number
+of arguments as read() in the output filters. [Stas]
+
+Implement $r->add_input_filter and $r->add_output_filter
+ $c->add_input_filter and $c->add_output_filter
+and add tests [Stas]
+
+Skip the handler package::func resolving error, only when the error
+message matches "Can't locate .*? in @INC", rather than just "Can't
+locate", since there are many other errors that start with that
+string. [Stas]
+
+the top level 'make test' now descends into the ModPerl-Registry dir
+to run 'make test' there [Stas]
+
+All response functions are now returning status and the callers check
+and croak on failure or progate them further. [Stas]
+
+OPEN, CLOSE and FILENO implementation for Apache::RequestRec [Stas]
+
+Another fix for the handling of the return status in
+ModPerl::RegistryCooker: reset the status to the original one only if
+it was changed by the script, otherwise return the execution status
+[Stas]
+
+prevent segfault in $r->print / $filter->print (in output filter) and
+related functions when they are called before the response phase
+[Stas]
+
+prevent segfault in send_http_header when it's called before the
+response phase [Stas]
+
+input stream filtering support was added + tests (plus renaming filter
+tests so we can know from the test name what kind of filter is tested)
+[Stas]
+
+Add proper support for mis-behaved feeding filters that send more than
+one EOS bucket in streaming filters + test. [Stas]
+
+prevent a segfault when push_handlers are used to push a handler into
+the currently phase and switching the handler (perl-script/modperl) +
+tests [Stas]
+
+Add $filter->seen_eos to the streaming filter api to know when eos has
+been seen, so special signatures can be passed and any data stored in
+the context flushed + tests. [Stas]
+
+Add $filter->ctx to maintain state between filter invocation + tests
+[Stas]
+
+Request input and output filters are now getting the EOS bucket, which
+wasn't passed through before. Now the context can be flushed on
+EOS. [Stas]
+
+
+
+=item 1.99_08 - January 10, 2003
+
+Correct ModPerl::RegistryCooker to reset %INC, after compile for .pl
+files which don't declare the package + add tests to check that [Stas]
+
+Log the real error message when Foo::Bar::sub_name fails to resolve,
+because of a problem in Foo::Bar, when Foo::Bar *was* found [Stas]
+
+Add PerlPreConnectionHandler support in Apache::Test [Stas]
+
+Enable PerlPreConnectionHandler [Stas]
+
+Support the Host: request header in Apache::TestClient [Stas]
+
+restore the ModPerl::RegistryLoader::new() method for backwards
+compatibility [Stas]
+
+port the support for NameWithVirtualHost in ModPerl::RegistryCooker
+and ModPerl::RegistryLoader [Stas]
+
+fix the handling of the return status in ModPerl::RegistryCooker, add
+a test to verify that [Stas]
+
+under non-threaded perl need to check whether mod_perl is running,
+when modperl_vhost_is_running check is done. [Stas]
+
+fix $r->read to read all the requested amount of data if possible,
+adjust the test TestApache::read to verify that [Stas]
+
+fix the method content() in Apache::compat to read a whole request
+body. same for ModPerl::Test::read_post. add tests. [Stas]
+
+Adjust the reverse filter test to work on win32 (remove trailing \r)
+[Randy Kobes <randy@theoryx5.uwinnipeg.ca>]
+
+Strongly suggest win32 users to upgrade to 5.8.0, if they run 5.6.x
+[Randy Kobes <randy@theoryx5.uwinnipeg.ca>]
+
+When installing the mod_perl shared object, first need to check
+whether the directory 'modules' already exists, and create it if not.
+[Randy Kobes <randy@theoryx5.uwinnipeg.ca>]
+
+Add a capability to tune the test configuration sections ordering
+in Apache::TestConfigPerl [Stas Bekman]
+
+fix the complaining code about late PerlSwitches when PerlLoadModule
+is used before it [Stas Bekman]
+
+add various tests that exercise PerlLoadModule and vhosts
+[Stas Bekman]
+
+handle correctly PerlLoadModules (directives) with vhosts:
+ - handle gracefully cases when things are undef/NULL
+ - handle the case when scfg==NULL, by stealing the base_servers's config
+[Stas Bekman]
+
+make mod_perl work with vhosts when the server is started prior to
+ post_config():
+ - call modperl_init_globals as early as possible, because the main server
+ record is needed during the configuration parsing, for perlloadmodule
+ and vhosts
+ - also make sure that we are using a real base_server, when dealing
+ with modperl_init, and if not retrieve it from the global record
+[Stas Bekman]
+
+prevent segfaults, when scfg is NULL in Apache::Module->get_config();
+[Stas Bekman]
+
+ensure that a core file is a file indeed, before complaining [Philippe
+M. Chiasson <gozer@cpan.org>]
+
+add $r->as_string [Geoffrey Young]
+
+add backcompat vars: $Apache::Server::CWD and
+$Apache::Server::AddPerlVersion [Stas Bekman]
+
+env var MOD_PERL_TRACE is working again [Stas Bekman]
+
+add a new test TestDirective::perlloadmodule2, which performs a more
+evolved merging. [Stas Bekman]
+
+fix Apache::TestConfigPerl under mod_perl 1.0, need to require
+mod_perl.pm before using $mod_perl::VERSION [Geoffrey Young]
+
+add an Apache::SIG backcompat stub to Apache::compat [Stas Bekman]
+
+fix the Apache::TestConfigPerl's run_apache_test_config() function
+where test packages are scanned for the magic APACHE_TEST_CONFIGURE
+and if found get require()'d. Apache2 needs to be run for mod_perl
+2.0. [Stas Bekman]
+
+move the custom mod_perl 2.0 configuration bits out of the
+ModPerl::TestRun, where they don't belong, into a special config file
+which is included at the very end of httpd.conf [Stas Bekman]
+
+extend Apache::Test to allow extra configuration files to be included
+at the very end of httpd.conf, when everything was loaded and
+configured [Stas Bekman]
+
+resolve a segfault in Apache::Module::get_config() for the edge case
+when the package name is bogus. [Stas Bekman]
+
+Apache::Reload: add support for watching and reloading modules only in
+specified sub-dirs [Harry Danilevsky <harry@deerfieldcapital.com>]
+
+enable APR.pm's linking for apr 0.9.2 and higher, which uses a new lib
+naming scheme, such as libapr-0.so.0.9.2, only if apr-config and
+apu-config scripts exist. [Stas Bekman]
+
+define IoTYPE_RDONLY/IoTYPE_WRONLY for perl-5.6.0 so the project
+compiles again under 5.6.0 [Stas Bekman]
+
+allow output streaming filters to append data to the end of the stream
+[Stas Bekman]
+
+fixes to compile with ActivePerl 5.8 beta
+[Randy Kobes <randy@theoryx5.uwinnipeg.ca>]
+
+fix for directive handlers within vhosts using threaded MPMs
+[Stephen Clouse <stephenc@theiqgroup.com>]
+
+fix <IfDefine MODPERL2> support
+
+default AuthType to Basic if not set in $r->get_basic_auth_pw()
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+workaround glibc/Perl-5.8.0 crypt() bug (seen with threaded MPMs)
+
+fix delete $ENV{$key} bug
+
+fix parse_args compat method to support non-ascii characters and tr/+/ /
+[Walery Studennikov <despair@sama.ru>]
+
+fix post_connection compat method to behave as it did in 1.x
+[Geoffrey Young]
+
+add support for setting $r->auth_name and $r->auth_type
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+add Apache->httpd_conf compat method
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+add default <Perl> handler Apache::PerlSection.
+make <Perl> blocks to be EXEC_ON_READ so apache does not parse the contents.
+add "Perl" directive for general use and for which <Perl> sections are
+stuffed into.
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+rename overloaded LoadModule directive to PerlLoadModule and adjust
+the test naming
+
+
+
+=item 1.99_07 - September 25, 2002
+
+fix =pod directive test config problem
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+
+
+=item 1.99_06 - September 25, 2002
+
+add support for pod directives (=pod,=back,=cut) and __END__ directive
+[Philippe M. Chiasson <gozer@cpan.org>]
+
+tweaks to support Test.pm 1.21 [Philippe M. Chiasson <gozer@cpan.org>]
+
+add $r->add_config method to add dynamic configuration at request time
+
+add Apache::DIR_MAGIC_TYPE constant
+
+add support for directive handlers
+
+fix source_scan to run with current httpd/apr
+
+add Apache::Server->add_config method to add dynamic configuration at
+server startup time
+
+add Apache::Directive->to_string method
+
+add support for pluggable <Perl> sections
+
+fix compilation probs with get_remote_host() that had a wrong
+prototype [Stas Bekman]
+
+Apache::SubProcess now has a manpage [Stas Bekman]
+
+fix the Apache::SubProcess tests to work with perlio-disabled Perl
+[Stas Bekman]
+
+fix the filehandle leak in APR::PerlIO (both perlio-disabled and
+perlio-enabled Perl) [Stas Bekman]
+
+remove dup() when converting filehandles from apr_file_t to FILE*
+under perlio-disabled Perl (APR::PerlIO) [Stas Bekman]
+
+fix compilation if apache/apr do not have thread support
+
+
+
+=item 1.99_05 - August 20, 2002
+
+fix PerlOptions +ParseHeaders to only parse once per-request
+
+add external redirects Registry tests [Stas Bekman]
+
+get rid of the compat layer in ModPerl-Registry [Stas Bekman]
+
+ModPerl::RegistryLoader is now fully operational and tested [Stas Bekman]
+
+Registry method handlers are now working [Stas Bekman]
+
+core Registry packages all compile the scripts into
+ModPerl::RegistryROOT:: namespace and cache them in
+%ModPerl::RegistryCache. Both overridable by the sub-classes. [Stas Bekman]
+
+compat tests were split into groups by functionality, send_fd test
+moved to compat. [Stas Bekman]
+
+added $c->get_remote_host and a compat wrapper $r->get_remote_host +
+tests [Stas Bekman]
+
+adjust the build system to support mod_perl build from the source
+tree. [Stas Bekman]
+
+ModPerl::RegistryCooker syncs with mod_perl 1.0's registry:
+ - prototypes defined checks in flush_namespace
+ [Yair Lenga <yair.lenga@citigroup.com>]
+ - set error-notes on error [Geoffrey Young]
+ - preserve status in Registry scripts [Geoffrey Young]
+
+apr_table_t is now an opaque type, use apr_table_elts() to get the array
+record [Stas Bekman]
+
+add support for redirects with PerlOptions +ParseHeaders
+
+backport to 2.0.35
+
+adjust to filter register api change
+
+added APR::ThreadMutex module
+
+
+
+=item 1.99_04 - June 21, 2002
+
+various APR PerlIO updates [Stas Bekman]
+
+stop using an apr_pool_t to allocate items for the interpreter pool,
+safer for threaded MPMs and prevents "leaks" when interpreters are
+removed from due to PerlInterpMax{Requests,Spare}
+
+implement modperl_sys_dlclose() to avoid apr/pool overhead/thread issues
+
+get the -DPERL_CORE optimization working again
+
+PERL_SET_CONTEXT to the parent interpreter when cloning interpreters at
+request time, else dTHX might be NULL during clone in the given thread,
+which would crash the server.
+
+
+
+=item 1.99_03 - June 15, 2002
+
+win32 fix for the global Apache->request object to make sure it uses
+the thread local storage mechanism
+
+add a reference count mechanism to interpreters for use in threaded MPMs,
+so if APR::Pool cleanups have been registered the interpreter is not
+putback into the interpreter pool until all cleanups have run.
+
+unbuffer STDERR (by turning on autoflush by default)
+
+add support for Perl*Handler +Apache::Foo
+
+fix open_logs,post_config,child_init hooks to run in the proper order
+
+adjust to apr_bucket_type_t changes in 2.0.37-dev
+[Mladen Turk <mturk@mappingsoft.com>]
+
+add MODPERL2 config define, as if the server had been started with -DMODPERL2
+
+compat additions and fixes: $r->lookup_{file,uri}, $r->is_main, Apache->define
+
+added compat for Apache::log_error [Stas Bekman]
+
+
+
+=item 1.99_02 - June 1, 2002
+
+pass the PATH and TZ environment variables at startup by default as 1.xx did
+
+fix ModPerl::Util::exit segv with 5.6.0
+
+no longer support 5.7.x perl development versions
+
+added compat for Apache::Table->new
+
+various fixes to compile/run on darwin
+
+server-scope Perl{Set,Pass}Env config now propagated to %ENV at startup
+
+use SvOK(sv) instead of sv == &PL_sv_undef to detect undef values in xs
+[Stephen Clouse <stephenc@theiqgroup.com>]
+
+complete Apache::Util 1.x compat
+
+added Apache::MPM_IS_THREADED constant
+
+added compat function for Apache::Constants::SERVER_VERSION
+
+added Apache::Constants::export stub for compat
+
+added noop stubs for timeout functions removed from 2.0:
+$r->{soft,hard,reset,kill}_timeout
+
+turned on PerlOptions +GlobalRequest by default for perl-script handler
+unless it is explicitly turned off with PerlOptions -GlobalRequest
+
+added APR::OS::thread_current function
+
+added support for 1.x $r->subprocess_env functionality
+
+added support for $r->push_handlers(PerlHandler => ...)
+
+added support for $r->proxyreq to detect proxy requests
+
+$r->content_type($val) now calls ap_set_content_type underneath
+
+add the err_header_out() wrapper to Apache::compat + corresponding tests
+[Stas Bekman]
+
+fix $r->dir_config lookup of values set in the server context
+
+added Apache::REDIRECT shortcut constant
+
+various fixes for method handlers
+
+use Apache::ServerUtil in Apache::compat so Apache->server works in compat
+mode [Dave Rolsky <autarch@urth.org>]
+
+add Apache::Util::unescape_uri alias to Apache::unescape_url in Apache::compat
+
+change Apache::unescape_url to return the escaped url as 1.x does
+
+disabled term coloring by default (enable with env var APACHE_TEST_COLOR=1)
+
+fix for APR::IpSubnet->new to check return status apr_ipsubnet_create
+
+enabled APR::SockAddr module
+
+turn on binmode for filehandle used in $r->send_fd
+
+get MP_{TRACE,DEBUG} Makefile.PL options working on win32
+
+various fixes to build/run with bleedperl
+
+various fixes for win32 to get make test passing
+
+moved constuct_{url,server} methods to Apache::URI module
+
+implement Apache::URI::parse in Apache::compat
+
+give Perl*Handlers precedence over other handlers by using APR_HOOK_FIRST
+rather than APR_HOOK_LAST
+
+workaround bug in 5.6.1 when XSLoader loads DynaLoader, wiping out any
+dl handles it had been keeping track of.
+
+tidy up test to run standalone (without modperl test config)
+[Stas Bekman]
+
+override T_PTROBJ INPUT typemap to croak if object is not a blessed
+reference, to prevent possible segv from e.g. Apache::Server->process
+
+apr_lock.h is gone; disable APR::Lock for the moment
+
+enabled the Apache::Process module
+
+fix ModPerl::Util::exit to clear $@ before calling Perl_croak
+
+cut down on some build noise
+
+fix 'PerlOptions +GlobalRequest' when used within subrequests
+
+get rid of some "subroutine redefined" warnings in ModPerl::MM that
+show up with newer bleedperls.
+
+a few fixes for Apache::compat [Dave Rolsky <autarch@urth.org>]
+
+
+
+=item 1.99_01 - April 6, 2002
+
+First public release of mod_perl-2.0-tobe.
+
+=back
+
+=cut
diff --git a/2_0_13/INSTALL b/2_0_13/INSTALL
new file mode 100644
index 0000000..e8c110b
--- /dev/null
+++ b/2_0_13/INSTALL
@@ -0,0 +1,40 @@
+Simple install:
+
+ % perl Makefile.PL MP_APXS=/usr/local/apache2/bin/apxs
+ % make && make test
+ % make install
+
+Simple install on AIX:
+
+ You will need GNU make to compile mod_perl. The AIX make does not work.
+ If you have installed GNU make from the AIX Toolbox:
+
+ % export MAKE="/opt/freeware/bin/gmake"
+ % perl Makefile.PL MP_APXS=/usr/local/apache2/bin/apxs
+ % gmake && gmake test
+ % gmake install
+
+Simple config:
+
+ LoadModule perl_module modules/mod_perl.so
+ #PerlModule Apache::compat
+ # your config comes here
+
+For a more detailed version (including more options) refer to:
+
+ docs/user/intro/start_fast.pod
+
+or online:
+
+ http://perl.apache.org/docs/2.0/user/intro/start_fast.html
+
+For an even more detailed documentation refer to:
+
+ docs/user/install/install.pod
+ docs/user/config/config.pod
+
+or online:
+
+ http://perl.apache.org/docs/2.0/user/install/install.pod
+ http://perl.apache.org/docs/2.0/user/config/config.pod
+
diff --git a/2_0_13/LICENSE b/2_0_13/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/2_0_13/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/2_0_13/META.yml b/2_0_13/META.yml
new file mode 100644
index 0000000..d652de7
--- /dev/null
+++ b/2_0_13/META.yml
@@ -0,0 +1,24 @@
+name: mod_perl
+version: 2.0.13
+installdirs: site
+distribution_type: module
+no_index:
+ directory:
+ # A-T and others have their own CPAN distros
+ - Apache-Test
+ - Apache-Reload
+ - Apache-SizeLimit
+ package:
+ # Internally redefined module
+ - C::Preprocessed
+ # Fake packages
+ - Apache::Status::_version
+ - perlrun_decl
+ # Apache::compat redefines
+ - Apache
+ - Apache::Constants
+ - Apache::File
+ - Apache::SIG
+ - Apache::Server
+ - Apache::Table
+ - Apache::Util
diff --git a/2_0_13/Makefile.PL b/2_0_13/Makefile.PL
new file mode 100644
index 0000000..2ceb943
--- /dev/null
+++ b/2_0_13/Makefile.PL
@@ -0,0 +1,947 @@
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+
+# useful for sub-Makefile.PL's to know whether they are invoked
+# directly or via the top level Makefile.PL
+$ENV{MOD_PERL_2_BUILD} = 1;
+
+use constant MIN_HTTPD_VERSION_DYNAMIC => '2.0.47';
+use constant MIN_HTTPD_VERSION_STATIC => '2.0.51';
+use constant MIN_HTTPD_24_VERSION => '2.4.0';
+
+my($old_modperl_version, $old_modperl_pm, $old_Apache2_pm);
+
+BEGIN {
+ eval {
+ my $old_mp2 = eval { require Apache2 };
+ require mod_perl;
+ if ($mod_perl::VERSION < 1.999_22 && $old_mp2) {
+ $old_modperl_version = $mod_perl::VERSION;
+ $old_modperl_pm = delete $INC{'mod_perl.pm'};
+ $old_Apache2_pm = delete $INC{'Apache2.pm'};
+ }
+ };
+
+}
+
+use lib qw(lib Apache-Test/lib);
+
+use Config;
+use File::Spec::Functions;
+use File::Spec;
+use DirHandle ();
+use File::Copy 'cp';
+use File::Basename qw(basename dirname);
+use File::Find ();
+
+use Apache2::Build ();
+use Apache::TestSmokePerl ();
+use Apache::TestTrace;
+use ModPerl::TestReport ();
+use ModPerl::TestRun ();
+use ModPerl::Code ();
+use ModPerl::BuildMM ();
+
+use constant WIN32 => Apache2::Build::WIN32;
+use constant BUILD_APREXT => Apache2::Build::BUILD_APREXT;
+
+our $VERSION;
+
+my $build = Apache2::Build->new(init => 1);
+my $code = ModPerl::Code->new;
+
+sub UNATTENDED() { $build->{MP_PROMPT_DEFAULT} || ! -t STDIN }
+
+# may populate $build->{MP_APXS}
+win32_fetch_apxs() if WIN32;
+
+configure();
+perl_version_check($build);
+
+local %ModPerl::BuildMM::PM = (
+ 'lib/typemap' => 'blib/lib/Apache2/typemap',
+);
+
+# these h files need to be installed system-wide so 3rd party XS
+# extensions can use them
+my @xs_h_files = map catfile("xs", $_),
+ qw(modperl_xs_sv_convert.h modperl_xs_typedefs.h modperl_xs_util.h
+ APR/PerlIO/modperl_apr_perlio.h);
+my @exe_files = map "bin/$_", qw(mp2bug);
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => 'mod_perl2',
+ VERSION => $VERSION,
+ DISTNAME => 'mod_perl',
+ NO_META => 1,
+ ABSTRACT_FROM => 'lib/mod_perl2.pm',
+ EXE_FILES => \@exe_files,
+ DEFINE => get_DEFINE(),
+ macro => {
+ MODPERL_SRC => $code->path,
+ MODPERL_MAKEFILE => basename($build->default_file('makefile')),
+ PERL => $build->perl_config('perlpath'),
+ MOD_INSTALL => ModPerl::BuildMM::mod_install(),
+ MODPERL_AP_INCLUDEDIR =>
+ $build->ap_destdir($build->install_headers_dir),
+ MODPERL_XS_H_FILES => join(" \\\n\t", @xs_h_files),
+ },
+ clean => {
+ FILES => "@{ clean_files() }",
+ },
+ dist => {
+ DIST_DEFAULT => 'mydist',
+ COMPRESS => 'gzip -9f', SUFFIX=>'gz',
+ PREOP => 'find $(DISTVNAME) -type d -print|xargs chmod 0755 && ' .
+ 'find $(DISTVNAME) -type f -print|xargs chmod 0644',
+ TO_UNIX => 'find $(DISTVNAME) -type f -print|xargs dos2unix'
+ },
+);
+
+post_configure();
+
+sub get_DEFINE {
+
+ my $opt_define = '';
+
+ # do we have apr libs?
+ # XXX: this define is really needed in xs/APR/APR/Makefile.PL, but this
+ # top-level Makefile.PL overrides MY::pasthru, and defines DEFINE= which
+ # overrides any local definition, not sure what's the right fix, for
+ # now just define it here (should it define PASTHRU_DEFINE instead?)
+ $opt_define = '-DMP_HAVE_APR_LIBS' if $build->apru_link_flags;
+
+ # preserve any DEFINE opts from outside and combine them with our
+ # local DEFINE
+ @ARGV = grep defined,
+ map { (/^DEFINE=(.*)/ && ($opt_define .= " $1")) ? undef : $_ } @ARGV;
+
+ return $opt_define;
+}
+
+sub configure {
+
+ # mod_perl test suite relies on having Apache-Test bundled with
+ # the mod_perl source, since any pre-installed version may not do
+ # the right thing
+ unless (-d "Apache-Test") {
+ error "Can't find a sub-directory Apache-Test. " .
+ "Make sure that you are using a complete source distribution";
+ exit 1;
+ }
+
+ set_modperl_version();
+
+ if ($old_modperl_version) {
+ (my $old_modperl_version_str = $old_modperl_version)
+ =~ s/(\d\d\d?)(\d\d)/$1_$2/;
+ my $vstring = "mod_perl/$old_modperl_version_str";
+ print "$vstring installation detected...";
+
+ my $prefix;
+ /^PREFIX=(.*)/ && $1 && ($prefix = canonpath glob($1)) for @ARGV;
+
+ # check that it's a full path
+ my $path = canonpath $old_modperl_pm;
+ # XXX: doesn't handle relative paths yet
+ # if PREFIX=/foo/bar is used, and it's not the same as the
+ # path where mod_perl < 1.999_22 is installed
+ if ($prefix && $path !~ /^$prefix/) {
+ print "ok (will install mod_perl/$VERSION into PREFIX=$prefix, " .
+ "no collision)\n";
+ }
+ else {
+ my $note = '';
+ if ($old_Apache2_pm) {
+ $note .= "Conflicting file: $old_Apache2_pm\n";
+ }
+ if ($path =~ /Apache2/ or $old_modperl_version > 1.99) {
+ my $dir = dirname $path;
+ # was it installed into the top-level?
+ $dir = catdir $dir, 'Apache' unless $path =~ /Apache2/;
+ $note .= "Conflicting dir: $dir\n" if -d $dir;
+ }
+
+ print " not ok\n\n";
+ print <<EOI;
+Cannot install mod_perl/$VERSION on top of $vstring
+due to a major API change between mod_perl 1.999_21 and 1.999_22.
+
+$note
+Please nuke the prior mod_perl installation from your site_lib,
+use a different perl to run the installation process, or use the
+PREFIX option when creating your Makefile. See:
+
+ http://perl.apache.org/docs/2.0/rename.html
+
+for more details.
+
+aborting...
+EOI
+ exit 1;
+ }
+ }
+ else {
+ print "no conflicting prior mod_perl version found - good.\n";
+
+ }
+
+ # On Win32, in order to decouple APR::* from mod_perl.so, we
+ # make up a static library MP_APR_LIB of the symbols required from
+ # src/modules/perl/*.c (see xs/APR/aprext/Makefile.PL), and
+ # then link APR/APR::* against this library. The reason for
+ # this is that, unlike Unix, if we had linked APR/APR::* against
+ # the mod_perl lib, then use of APR/APR::* would demand mod_perl.so
+ # be available, even if these symbols are supplied by another
+ # loaded library (which is done for unix by APR.so - see
+ # xs/APR/APR/Makefile.PL). This also means we must ensure the
+ # MP_APR_LIB lib is built before any of the APR/APR::* modules
+ # (see the aprext target in the MY::top_targets sub below), as
+ # symbols must get resolved at link time.
+
+ if (BUILD_APREXT()) {
+ require File::Path;
+ #Makefile.PL's in WrapXS/ just need to pass the -e mod_perl.lib test
+ #the real mod_perl.lib will be in place when WrapXS/ dll's are
+ #actually linked
+ # this must also be done for aprext.lib, build in xs/APR/aprext/;
+ # we must create a dummy aprext.lib to pass the -e test.
+ my $lib1 = catfile qw(src modules perl),
+ $build->{MP_LIBNAME} . $Config{lib_ext};
+ my ($apr_blib, $full_libname) = $build->mp_apr_blib();
+ my $lib2 = catfile $apr_blib, $full_libname;
+ unless (-d $apr_blib) {
+ File::Path::mkpath($apr_blib) or die "mkdir $apr_blib failed: $!";
+ }
+ foreach my $lib ($lib1, $lib2) {
+ unless (-e $lib) {
+ open my $fh, '>', $lib or die "open $lib: $!";
+ print $fh "#this is a dummy file to trick MakeMaker";
+ close $fh;
+ }
+ }
+ }
+
+ system_sanity_check();
+
+ my $min_httpd_version = $build->should_build_apache
+ ? MIN_HTTPD_VERSION_STATIC
+ : MIN_HTTPD_VERSION_DYNAMIC;
+
+ if ($build->{MP_APXS}) {
+ print "Using APXS => $build->{MP_APXS}\n";
+ }
+ elsif ($build->{MP_AP_PREFIX}) {
+ if (my $reason = $build->ap_prefix_invalid) {
+ error "invalid MP_AP_PREFIX: $reason";
+ exit 1;
+ }
+ print "Using Apache prefix => $build->{MP_AP_PREFIX}\n";
+ }
+ else {
+ unless ($build->{MP_USE_STATIC}) {
+ # may populate $build->{MP_APXS}
+ prompt_for_apxs($build);
+ }
+ }
+
+ $build->{$_} and $ENV{$_} = $build->{$_} for (qw/MP_APXS MP_AP_PREFIX/);
+
+ unless ($build->{MP_APXS} or $build->{MP_AP_PREFIX}) {
+ my $ok = 0;
+ for my $path ($build->find) {
+ $build->dir($path);
+ my $mmn = $build->module_magic_number;
+ my $v = $build->httpd_version;
+ next unless $v;
+ next if $v lt $min_httpd_version;
+ $ok++ if $build->prompt_y("Configure mod_perl with $path?");
+ last if $ok;
+ }
+ until ($ok) {
+ my $ask = "Please provide the location of the Apache directory:";
+ my $ans = $build->prompt($ask) || "";
+ # strip leading/closing spaces
+ $ans =~ s/^\s*|\s*$//g;
+ if (defined $ans and -d $ans) {
+ $build->dir($ans);
+ $ok++;
+ }
+ else {
+ error "Can't find dir '$ans'";
+ last if UNATTENDED;
+ }
+ }
+ }
+
+ if ($build->should_build_apache) {
+ $build->configure_apache();
+ }
+
+ my $httpd_version = $build->httpd_version;
+ unless ($httpd_version) {
+ error 'Unable to determine server version, aborting.';
+ if ($build->{MP_APXS} || $build->{MP_AP_PREFIX}) {
+ my $what = $build->{MP_APXS} ? 'MP_APXS' : 'MP_AP_PREFIX';
+ error "Invalid $what specified?";
+ }
+ else {
+ error 'Please specify MP_APXS or MP_AP_PREFIX.';
+ }
+ exit(1);
+ }
+
+ if ($httpd_version lt $min_httpd_version) {
+ error "Apache/$httpd_version not supported, " .
+ "$min_httpd_version or higher is required";
+ exit(1);
+ }
+
+ printf "Configuring Apache/%s mod_perl/%s Perl/v%vd\n",
+ $httpd_version, $VERSION, $^V;
+
+ my $apr_config = $build->get_apr_config; #cache it
+
+ # we need to know where apr-config and apu-configs are
+ # which sometimes aren't placed into the same dir with apxs/httpd
+ # XXX: need to fix that for WIN32
+ # XXX: when the source tree is used, there is not much use for apr-config
+ unless (WIN32 || $build->apr_config_path || $build->httpd_is_source_tree) {
+ error "can't find 'apr-config', please pass " .
+ "MP_APR_CONFIG=/full/path/to/apr-config to 'perl Makefile.PL'";
+ exit 1;
+ }
+
+ for (@{ clean_files() }) {
+ debug "unlink...$_" if -e $_ && unlink;
+ }
+
+ #ModPerl::BuildMM will use Apache2::BuildConfig in subdir/Makefile.PL's
+ $build->save;
+
+ ModPerl::TestRun->generate_script;
+ ModPerl::TestReport->generate_script;
+ Apache::TestSmokePerl->generate_script;
+
+ my $tables_dir = tables_dir($httpd_version);
+
+ unshift @INC, $tables_dir;
+
+ if ($build->{MP_GENERATE_XS}) {
+ debug "generating XS code using $tables_dir...";
+ xs_generate($httpd_version);
+ }
+
+ install_typemap();
+}
+
+sub prompt_for_apxs {
+ my $build = shift;
+
+ print <<EOI;
+
+Next we need to know where the 'apxs' script is located. This script
+provides a lot of information about the Apache installation, and makes
+it easier to find things on your system. Normally it's located in the
+same directory as the 'httpd' executable.
+
+If you don't yet have Apache installed you can build Apache against
+the Apache source code, but you won't be able to run the test suite (a
+very important step). Therefore you may want to install Apache before
+proceeding.
+
+EOI
+
+ my $prompt = "\nPlease provide a full path to 'apxs' executable\n" .
+ "(press Enter if you don't have it installed):";
+ while (1) {
+ my $ans = $build->prompt($prompt) || "";
+
+ print "\n\n";
+
+ # strip leading/closing spaces
+ $ans =~ s/^\s*|\s*$//g;
+
+ last unless length $ans; # skip
+
+ unless (File::Spec->file_name_is_absolute($ans)) {
+ warn "The path '$ans' is not an absolute path. " .
+ "Please specify an absolute path.\n";
+ next;
+ }
+
+ warn("'$ans' doesn't exist.\n"), next unless -e $ans;
+ warn("'$ans' is not a file.\n"), next unless -f _;
+ warn("'$ans' is not executable.\n"), next unless -x _;
+
+ $build->{MP_APXS} = $ans;
+ last;
+ }
+}
+
+sub post_configure {
+
+ #now have any data subdir/Makefile.PL's save, e.g. XS
+ $build = Apache2::Build->build_config;
+
+ $build->write_src_makefile;
+ $build->save_ldopts;
+
+ $code->generate($build);
+
+ for my $type (qw(DSO STATIC)) {
+ next unless $build->{"MP_USE_$type"};
+ warning "mod_perl \L$type\E library will be built as ".
+ $build->{"MODPERL_LIB_$type"};
+ }
+
+ if ($build->is_dynamic) {
+ warning
+ "You'll need to add the following to httpd.conf:", "",
+ " LoadModule perl_module modules/$build->{MODPERL_LIB_DSO}", "",
+ "depending on your build, mod_perl might not live in",
+ "the modules/ directory.\n";
+ if ($build->{MP_APXS}) {
+ warning
+ "Check the results of", "",
+ " \$ $build->{MP_APXS} -q LIBEXECDIR", "",
+ "and adjust the LoadModule directive accordingly.\n";
+ }
+ }
+
+ $build->save;
+}
+
+sub tables_dir {
+ my $httpd_version = shift;
+
+ my $tables_version='';
+ if ($httpd_version lt MIN_HTTPD_24_VERSION) {
+ $tables_version='current';
+ }
+ else {
+ $tables_version='current24';
+ }
+
+ my $tables_dir = "xs/tables/$tables_version";
+}
+
+sub xs_generate {
+ require ModPerl::WrapXS;
+
+ my $xs = ModPerl::WrapXS->new;
+
+ $xs->generate;
+
+ #shift @INC; #ModPerl::Code needs this path too
+}
+
+sub install_typemap {
+ my $to_file = 'lib/typemap';
+
+ open my $to_fh, ">$to_file" or die "open $to_file: $!";
+
+ for my $from_file (qw(WrapXS/typemap xs/typemap)) {
+ open my $from_fh, $from_file or die "open $from_file: $!";
+ cp $from_fh, $to_fh;
+ close $from_fh;
+ }
+
+ close $to_fh or die "close $to_file: $!";
+}
+
+sub echo_cmd {
+ my $cmd = shift;
+ print "$cmd\n";
+ system($cmd) == 0 or exit(1);
+}
+
+sub clean_files {
+ my $path = $code->path;
+
+ my @files = ();
+ File::Find::find(sub { push @files, "$File::Find::dir/$_" if -f $_},
+ "WrapXS") if -d "WrapXS";
+
+ push @files, map { "xs/$_.h" }
+ qw(modperl_xs_typedefs modperl_xs_sv_convert);
+
+ return [@{ $build->clean_files },
+ @files,
+ qw(lib/typemap
+ lib/ModPerl/MethodLookup.pm
+ lib/ModPerl/DummyVersions.pm
+ t/htdocs/vhost/error_log
+ t/SMOKE
+ t/TEST
+ t/REPORT
+ ),
+ <t/htdocs/hooks/startup/open_logs*>,
+ <t/htdocs/hooks/startup/post_config*>,
+ <xs/*.exp>,
+ <xs/*.def>,
+ map { "$path/$_"} @{ $code->clean_files }
+ ];
+}
+
+sub set_modperl_version {
+ require './lib/mod_perl2.pm';
+
+ $VERSION = $mod_perl2::VERSION_TRIPLET;
+
+ open my $fh, 'Changes';
+ while (<$fh>) {
+ if (/^=item\s+\Q$VERSION\E-(dev|rc\d+)/) {
+ $VERSION .= "-$1";
+ last;
+ }
+ last if /^=item/;
+ }
+ close $fh;
+
+ $build->{VERSION} = $VERSION;
+ $build->{API_VERSION} = $mod_perl2::API_VERSION;
+}
+
+# needs to be run after configure() when apxs is setup
+sub perl_version_check {
+ my $build = shift;
+
+ my $perl_version = $];
+ $perl_version =~ s/5.00(\d)(?:00(\d))?/"5.$1." . ($2||0)/e;
+ my $perl_threads = Apache2::Build::PERL_HAS_ITHREADS ? "w/" : "w/o";
+ my $perl_string = "Using Perl $perl_version $perl_threads ithreads";
+ my $httpd_version = $build->httpd_version;
+ my $mpm = "";
+ my $build_threaded = 0;
+
+ # For httpd-2.4, we can't use mpm_is_threaded(), because MPMs are loadable
+ # modules. We therefore treat httpd as a whole project as threaded. It is
+ # still possible to disable threading by using MP_NO_THREADS=1
+ if ($httpd_version lt MIN_HTTPD_24_VERSION) {
+ $build_threaded = $build->mpm_is_threaded();
+ $mpm = $build->mpm_name();
+ }
+ else {
+ if ($build->{MP_NO_THREADS}) {
+ $build_threaded = 0;
+ }
+ else {
+ $build_threaded = 1;
+ }
+ }
+
+ # certain mpms require perl 5.8.0+ w/ithreads
+ if ($build_threaded) {
+ my @fail;
+ push @fail, "Perl 5.8 or higher"
+ unless $] >= 5.008;
+ push @fail, "Perl built with ithreads (build perl with -Duseithreads)"
+ unless Apache2::Build::PERL_HAS_ITHREADS();
+ if (@fail) {
+ if ($httpd_version lt MIN_HTTPD_24_VERSION) {
+ error "$perl_string and '$mpm' mpm httpd.",
+ "Failed requirements:",
+ join "", map {" - $_\n"} @fail;
+ }
+ else {
+ error "$perl_string and httpd-2.4.",
+ "Failed requirements:",
+ join "", map {" - $_\n"} @fail;
+ }
+ exit 1;
+ }
+ }
+ else {
+ # before 5.8.2, perl_shutdown is incomplete (in the case of ithreads
+ # each PerlInterpreter * gets tossed so it works)
+ if ($build->should_build_apache && !Apache2::Build::PERL_HAS_ITHREADS) {
+ # before 5.8.2, perl_shutdown is incomplete
+ if ($] < 5.008_002) {
+ if ($httpd_version lt MIN_HTTPD_24_VERSION) {
+ error "static $mpm mpm requires a threaded ".
+ "perl 5.6.1-5.8.1 or any perl 5.8.2+";
+ }
+ else {
+ error "httpd-2.4 requires a threaded ".
+ "perl 5.6.1-5.8.1 or any perl 5.8.2+";
+ }
+ exit 1;
+ }
+ }
+ }
+
+ if ($] < 5.006_001) {
+ error "$perl_string. You need at least Perl 5.6.1";
+ exit 1;
+ }
+
+ if ($] >= 5.007 and $] < 5.008) {
+ error "$perl_string.",
+ "5.7.x development versions of Perl are no longer supported",
+ "Upgrade to Perl 5.8.0 or higher";
+ exit 1;
+ }
+
+ if ($Config{usemultiplicity} xor $Config{useithreads}) {
+ error "mod_perl does not currently support multiplicity without ".
+ "ithreads.";
+ if ($build_threaded) {
+ error "Please recompile Perl with -Duseithreads and ".
+ "-Dusemultiplicity";
+ } else {
+ error "Please recompile Perl with either -Duseithreads and ".
+ "-Dusemultiplicity or -Uuseithreads and -Uusemultiplicity";
+ }
+ exit 1;
+ }
+}
+
+sub system_sanity_check {
+ return if WIN32;
+
+ my $ccflags = $build->perl_config('ccflags');
+ for (split /\s+/, $ccflags) {
+ next unless s/^-I//;
+ my $header = "$_/ap_mmn.h";
+ if (-e $header) {
+ $build->phat_warn(<<EOF);
+Apache headers found in unexpected location: ``$_'', suggestions:
+ *) Remove via ``rpm -e apache''
+ *) Remove by hand
+ *) Complain to your os vendor about their poor layout choice
+ *) Complain to your sysadmin about their poor layout choice
+EOF
+ }
+ }
+
+ $build->lib_check('gdbm');
+ malloc_check();
+ os_check();
+}
+
+sub malloc_check {
+ return unless $build->is_dynamic;
+ return unless $build->perl_config('usemymalloc') eq 'y';
+
+ my $abort = $^O eq 'solaris';
+
+ my $bincompat = $build->perl_config('bincompat5005');
+
+ if ($bincompat) {
+ $build->phat_warn(<<EOF, $abort);
+Your current configuration will most likely trigger core dumps, suggestions:
+ *) Do not configure mod_perl as a DSO
+ *) Rebuild Perl without malloc pollution (Configure -Ubincompat5005)
+EOF
+ }
+}
+
+sub os_check {
+ my $check = \&{"os_check_$^O"};
+ return unless defined &$check;
+ $check->()
+}
+
+sub os_check_hpux {
+ my $ccflags = $build->perl_config('ccflags');
+ my $ld = $build->perl_config('ld');
+
+ if ($build->is_dynamic and $ld eq 'ld') {
+ unless ($ccflags =~ /\+z/i) {
+ $build->phat_warn(<<EOF);
+mod_perl is unlikely to link with your libperl, suggestions:
+ *) Rebuild Perl with Configure -Accflags=+Z ...
+EOF
+ }
+ }
+}
+
+sub win32_fetch_apxs {
+ return unless (my $prefix = $build->{MP_AP_PREFIX});
+ my $script = catfile($build->{cwd}, 'build', 'win32_fetch_apxs');
+ my @args = ($^X, $script, "--with-apache2=$prefix");
+ system(@args) == 0 or die "system @args failed: $?";
+ my $apxs = catfile($prefix, 'bin', 'apxs.bat');
+ $build->{MP_APXS} = $apxs if -e $apxs;
+}
+
+
+package MY;
+
+use Config;
+use constant WIN32 => $^O eq 'MSWin32';
+use constant BUILD_APREXT => Apache2::Build::BUILD_APREXT;
+
+sub MY::top_targets {
+ my $self = shift;
+ my $string = $self->ModPerl::BuildMM::MY::top_targets;
+
+ if (BUILD_APREXT) {
+ ModPerl::MM::add_dep(\$string, pure_all => 'aprext');
+
+ # must not import File::Spec functions inside MY, it breaks
+ # 5.6.x builds
+ my ($apr_blib, $full_libname) = $build->mp_apr_blib();
+ my $from = File::Spec->catfile($apr_blib, $full_libname);
+ (my $ap_lib = $build->ap_includedir()) =~ s{include$}{lib};
+ my $to = File::Spec->catfile($ap_lib, $full_libname);
+ my $src_dir = File::Spec->catdir(qw(xs APR), 'aprext');
+ $string .= <<"EOF";
+
+aprext:
+ cd "$src_dir" && \$(MAKE) all \$(PASTHRU) LINKTYPE="static"
+
+aprext_install:
+ \@\$(MKPATH) "$ap_lib"
+ \$(CP) "$from" "$to"
+
+EOF
+ }
+
+ if ($build->should_build_apache) {
+ ModPerl::MM::add_dep(\$string, pure_all => 'ap_build');
+ $string .= <<"EOF";
+ap_build: modperl_lib
+ cd "$build->{MP_AP_PREFIX}" && make
+
+ap_install: ap_build
+ cd "$build->{MP_AP_PREFIX}" && make DESTDIR=\$(DESTDIR) install
+EOF
+ }
+
+ ModPerl::MM::add_dep(\$string, pure_all => 'modperl_lib');
+
+ $string .= <<'EOF';
+
+source_scan:
+ $(PERL) build/source_scan.pl
+
+xs_generate:
+ $(PERL) build/xs_generate.pl
+
+bugreport:
+ $(PERL) bin/mp2bug
+
+etags:
+ $(SHELL) build/make_etags
+
+modperl_lib:
+ cd "$(MODPERL_SRC)" && $(MAKE)
+
+modperl_lib_install:
+ cd "$(MODPERL_SRC)" && $(MAKE) DESTDIR=$(DESTDIR) install
+
+modperl_xs_h_install:
+ @$(MKPATH) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR)
+ $(CP) $(MODPERL_XS_H_FILES) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR)
+
+modperl_src_clean:
+ cd "$(MODPERL_SRC)" && $(MAKE) clean
+
+EOF
+
+ # $(ECHO) was broken before 6.10_01
+ # XXX: if ever require 6.11 we can remove this workaround
+ require ExtUtils::MakeMaker;
+ (my $mm_ver = ExtUtils::MakeMaker->VERSION) =~ s/_\d+//;
+ my $say = $mm_ver > 6.10
+ ? '@$(ECHO)'
+ : '@$(PERL) -le "print shift"';
+
+ $string .= <<"EOF";
+modperl_banner:
+ $say "+--------------------------------------------------------------+"
+ $say "| |"
+ $say "| For details on getting started with mod_perl 2, see: |"
+ $say "| |"
+ $say "| http://perl.apache.org/docs/2.0/user/intro/start_fast.html |"
+ $say "| |"
+ $say "| |"
+ $say "| Found a bug? File a bug report: |"
+ $say "| |"
+ $say "| http://perl.apache.org/bugs/ |"
+ $say "| |"
+ $say "+--------------------------------------------------------------+"
+
+EOF
+
+ $string;
+}
+
+sub MY::install {
+ my $self = shift;
+ my $string = $self->MM::install(@_);
+
+ for my $kind ('', '_site', '_vendor') {
+ ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'ap_install')
+ if $build->should_build_apache;
+ ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'modperl_lib_install');
+ ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'modperl_xs_h_install');
+ # ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'aprext_install')
+ # if BUILD_APREXT;
+
+ ModPerl::MM::add_dep_after(\$string, "install$kind", "doc${kind}_install", 'modperl_banner');
+
+ # glue_pods target must come first
+ ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'glue_pods');
+ }
+
+ $string;
+}
+
+sub MY::clean {
+ my $self = shift;
+ my $string = $self->MM::clean(@_);
+ ModPerl::MM::add_dep(\$string, clean => 'modperl_src_clean');
+ ModPerl::MM::add_dep(\$string, clean => 'test_clean');
+ $string;
+}
+
+sub MY::test {
+
+ my $preamble;
+ if (Apache::TestConfig::WIN32) {
+ # need to add the location of Apache's dlls to the PATH
+ my $ap_bindir = $build->apr_bindir() || '';
+ unless ($ap_bindir) {
+ $ap_bindir = File::Spec->catdir($build->{MP_AP_PREFIX}, 'bin')
+ if $build->{MP_AP_PREFIX};
+ }
+ my $modperl_libexecdir = '';
+ if ($build->is_dynamic) {
+ # need to add the location of mod_perl.so to the PATH
+ my $lib = $build->modperl_libpath() || '';
+ if ($lib) {
+ $modperl_libexecdir = File::Basename::dirname($lib);
+ }
+ else {
+ $modperl_libexecdir = File::Spec->catdir($build->{cwd},
+ 'src/modules/perl')
+ if $build->{cwd};
+ }
+ }
+ my $extra_path = '';
+ $extra_path .= ";$ap_bindir" if $ap_bindir;
+ $extra_path .= ";$modperl_libexecdir" if $modperl_libexecdir;
+ $preamble = <<EOF;
+PATH = \$(PATH)$extra_path
+EOF
+ }
+ else {
+ # PASSENV confuses the Win32 command-line build
+ my $env = Apache::TestConfig->passenv_makestr();
+ $preamble = <<EOF;
+PASSENV = $env
+EOF
+ }
+
+ $preamble .= <<'EOF';
+TEST_VERBOSE = 0
+TEST_FILES =
+
+test_clean :
+ $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \
+ t/TEST -clean
+
+run_tests : test_clean
+ $(PASSENV) \
+ $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \
+ t/TEST -bugreport -verbose=$(TEST_VERBOSE) $(TEST_FILES)
+
+run_subtests ::
+ cd ModPerl-Registry && $(MAKE) test
+
+run_subtests ::
+ cd Apache-Reload && $(MAKE) test
+
+EOF
+
+ $preamble .= <<'EOF' unless $build->mpm_is_threaded();
+run_subtests ::
+ cd Apache-SizeLimit && $(MAKE) test
+
+EOF
+
+ $preamble .= <<'EOF';
+test :: pure_all run_tests run_subtests
+EOF
+
+ return $preamble;
+}
+
+sub MY::postamble {
+ my $self = shift;
+
+ my $string = $self->ModPerl::BuildMM::MY::postamble;
+
+ if (!WIN32) {
+ $string .= <<'EOF';
+rpm: dist
+ @[ -d $(PWD)/rpm ] || mkdir $(PWD)/rpm
+ rpmbuild -ta --define "_rpmdir $(PWD)/rpm" \
+ --define "_srcrpmdir $(PWD)/rpm" \
+ $(DISTVNAME).tar.gz
+ @mv $(PWD)/rpm/*/*.rpm $(PWD)/rpm/
+ @rm -rf $(PWD)/rpm/*/
+
+EOF
+ }
+
+ my $q = (WIN32 ? '"' : "'");
+
+ $string .= <<"EOF";
+mydist : Apache-Test/META.yml mod_perl.spec manifest tardist
+
+mod_perl.spec: build/make_rpm_spec
+ \$(PERL) build/make_rpm_spec
+
+Apache-Test/META.yml:
+ cd Apache-Test && make metafile
+
+tag :
+ svn copy -m $q\$(VERSION_SYM) release branch$q https://svn.apache.org/repos/asf/perl/modperl/trunk https://svn.apache.org/repos/asf/perl/modperl/branches/release/\$(VERSION_SYM)
+ svn copy -m $q\$(VERSION_SYM) tag$q https://svn.apache.org/repos/asf/perl/modperl/branches/release/\$(VERSION_SYM) https://svn.apache.org/repos/asf/perl/modperl/tags/\$(VERSION_SYM)
+ svn copy -m $q\$(VERSION_SYM) tag$q https://svn.apache.org/repos/asf/perl/modperl/docs/trunk https://svn.apache.org/repos/asf/perl/modperl/docs/tags/\$(VERSION_SYM)
+EOF
+
+ return $string;
+}
+
+# this is a workaround so that ModPerl::MM will move MY::constants
+# away, and Apache-Test/Makefile.PL which has its own MY::constants
+# won't get complaints on MY::constants redefined
+sub MY::constants {
+ shift->ModPerl::BuildMM::MY::constants;
+}
+
+sub MY::tool_autosplit {
+ '';
+}
+
+sub MY::manifypods {
+ my $self = shift;
+ my $ver = $self->{VERSION} || "";
+ local $_ = $self->MM::manifypods(@_);
+ s/pod2man\s*$/pod2man --release mod_perl-$ver/m;
+ $_;
+}
+
+sub MY::pasthru {
+ my $self = shift;
+ chomp(my $str = $self->MM::pasthru);
+ join $/, "$str\\",
+ "\t".'PERL="$(PERL)"\\',
+ "\t".'DEFINE="$(DEFINE)"',
+ "";
+}
+
+sub MY::dist_basics {
+ my $self = shift;
+ my $str = $self->MM::dist_basics;
+
+ $str =~ s/(\"?)-MExtUtils(::Manifest=mkmanifest)/-Ilib $1-MModPerl$2/;
+
+ $str;
+}
diff --git a/2_0_13/ModPerl-Registry/MANIFEST b/2_0_13/ModPerl-Registry/MANIFEST
new file mode 100644
index 0000000..88a5ab6
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/MANIFEST
@@ -0,0 +1,19 @@
+MANIFEST This list of files
+Makefile.PL
+README
+TODO
+lib/ModPerl/PerlRun.pm
+lib/ModPerl/Registry.pm
+lib/ModPerl/RegistryBB.pm
+lib/ModPerl/RegistryCooker.pm
+t/TEST.PL
+t/basic.t
+t/closure.t
+t/cgi-bin/basic.pl
+t/cgi-bin/closure.pl
+t/cgi-bin/env.pl
+t/cgi-bin/local-conf.pl
+t/cgi-bin/not_executable.pl
+t/cgi-bin/require.pl
+t/conf/extra.conf.in
+
diff --git a/2_0_13/ModPerl-Registry/Makefile.PL b/2_0_13/ModPerl-Registry/Makefile.PL
new file mode 100644
index 0000000..0184b4c
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/Makefile.PL
@@ -0,0 +1,44 @@
+use strict;
+use warnings FATAL => 'all';
+no warnings 'redefine';
+
+use FindBin;
+use lib grep { -d } map "$FindBin::Bin/../$_", qw(lib Apache-Test/lib);
+
+use ModPerl::BuildMM ();
+use Apache::TestSmokePerl ();
+use Apache2::Build ();
+
+# enable 'make test|clean'
+use Apache::TestMM qw(test clean);
+
+# prerequisites
+my %require = (
+ "Apache::Test" => "0", # any version will do?
+);
+
+my @scripts = qw(t/TEST t/SMOKE);
+
+# accept the configs from comman line
+Apache::TestMM::filter_args();
+
+my $build = Apache2::Build->build_config;
+if ($build->should_build_apache) {
+ push @Apache::TestMM::Argv, ('httpd' => $build->{httpd});
+}
+Apache::TestMM::generate_script('t/TEST');
+
+# t/SMOKE
+Apache::TestSmokePerl->generate_script;
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => 'ModPerl::Registry',
+ VERSION_FROM => 'lib/ModPerl/RegistryCooker.pm',
+ PREREQ_PM => \%require,
+ clean => {
+ FILES => "@{ clean_files() }",
+ });
+
+sub clean_files {
+ return [@scripts, 'Makefile.old'];
+}
diff --git a/2_0_13/ModPerl-Registry/README b/2_0_13/ModPerl-Registry/README
new file mode 100644
index 0000000..a1ee07b
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/README
@@ -0,0 +1 @@
+to be written
diff --git a/2_0_13/ModPerl-Registry/TODO b/2_0_13/ModPerl-Registry/TODO
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/TODO
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRun.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRun.pm
new file mode 100644
index 0000000..9dc3ce9
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRun.pm
@@ -0,0 +1,79 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::PerlRun;
+
+use strict;
+use warnings FATAL => 'all';
+
+# we try to develop so we reload ourselves without die'ing on the warning
+no warnings qw(redefine); # XXX, this should go away in production!
+
+our $VERSION = '1.99';
+
+use base qw(ModPerl::RegistryCooker);
+
+sub handler : method {
+ my $class = (@_ >= 2) ? shift : __PACKAGE__;
+ my $r = shift;
+ return $class->new($r)->default_handler();
+}
+
+my $parent = 'ModPerl::RegistryCooker';
+# the following code:
+# - specifies package's behavior different from default of $parent class
+# - speeds things up by shortcutting @ISA search, so even if the
+# default is used we still use the alias
+my %aliases = (
+ new => 'new',
+ init => 'init',
+ default_handler => 'default_handler',
+ run => 'run',
+ can_compile => 'can_compile',
+ make_namespace => 'make_namespace',
+ namespace_root => 'namespace_root',
+ namespace_from => 'namespace_from_filename',
+ is_cached => 'FALSE',
+ should_compile => 'TRUE',
+ flush_namespace => 'flush_namespace_normal',
+ cache_table => 'cache_table_common',
+ cache_it => 'NOP',
+ read_script => 'read_script',
+ shebang_to_perl => 'shebang_to_perl',
+ get_script_name => 'get_script_name',
+ chdir_file => 'NOP',
+ get_mark_line => 'get_mark_line',
+ compile => 'compile',
+ error_check => 'error_check',
+ should_reset_inc_hash => 'TRUE',
+ strip_end_data_segment => 'strip_end_data_segment',
+ convert_script_to_compiled_handler => 'convert_script_to_compiled_handler',
+);
+
+# in this module, all the methods are inherited from the same parent
+# class, so we fixup aliases instead of using the source package in
+# first place.
+$aliases{$_} = $parent . "::" . $aliases{$_} for keys %aliases;
+
+__PACKAGE__->install_aliases(\%aliases);
+
+
+
+
+
+1;
+__END__
+
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRunPrefork.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRunPrefork.pm
new file mode 100644
index 0000000..445e599
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRunPrefork.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package ModPerl::PerlRunPrefork;
+
+use strict;
+use warnings FATAL => 'all';
+
+our $VERSION = '0.01';
+
+use base qw(ModPerl::PerlRun);
+
+if ($ENV{MOD_PERL}) {
+ require Apache2::MPM;
+ die "This package can't be used under threaded MPMs"
+ if Apache2::MPM->is_threaded;
+}
+
+sub handler : method {
+ my $class = (@_ >= 2) ? shift : __PACKAGE__;
+ my $r = shift;
+ return $class->new($r)->default_handler();
+}
+
+*chdir_file = \&ModPerl::RegistryCooker::chdir_file_normal;
+
+1;
+__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/Registry.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/Registry.pm
new file mode 100644
index 0000000..9d7904e
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/Registry.pm
@@ -0,0 +1,85 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::Registry;
+
+use strict;
+use warnings FATAL => 'all';
+
+# we try to develop so we reload ourselves without die'ing on the warning
+no warnings qw(redefine); # XXX, this should go away in production!
+
+our $VERSION = '1.99';
+
+use base qw(ModPerl::RegistryCooker);
+
+sub handler : method {
+ my $class = (@_ >= 2) ? shift : __PACKAGE__;
+ my $r = shift;
+ return $class->new($r)->default_handler();
+}
+
+my $parent = 'ModPerl::RegistryCooker';
+# the following code:
+# - specifies package's behavior different from default of $parent class
+# - speeds things up by shortcutting @ISA search, so even if the
+# default is used we still use the alias
+my %aliases = (
+ new => 'new',
+ init => 'init',
+ default_handler => 'default_handler',
+ run => 'run',
+ can_compile => 'can_compile',
+ make_namespace => 'make_namespace',
+ namespace_root => 'namespace_root',
+ namespace_from => 'namespace_from_filename',
+ is_cached => 'is_cached',
+ should_compile => 'should_compile_if_modified',
+ flush_namespace => 'NOP',
+ cache_table => 'cache_table_common',
+ cache_it => 'cache_it',
+ read_script => 'read_script',
+ shebang_to_perl => 'shebang_to_perl',
+ get_script_name => 'get_script_name',
+ chdir_file => 'NOP',
+ get_mark_line => 'get_mark_line',
+ compile => 'compile',
+ error_check => 'error_check',
+ strip_end_data_segment => 'strip_end_data_segment',
+ convert_script_to_compiled_handler => 'convert_script_to_compiled_handler',
+);
+
+# in this module, all the methods are inherited from the same parent
+# class, so we fixup aliases instead of using the source package in
+# first place.
+$aliases{$_} = $parent . "::" . $aliases{$_} for keys %aliases;
+
+__PACKAGE__->install_aliases(\%aliases);
+
+# Note that you don't have to do the aliases if you use defaults, it
+# just speeds things up the first time the sub runs, after that
+# methods are cached.
+#
+# But it's still handy, since you explicitly specify which subs from
+# the parent package you are using
+#
+
+# META: if the ISA search results are cached on the first lookup, may
+# be we need to alias only those methods that override the defaults?
+
+
+1;
+__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryBB.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryBB.pm
new file mode 100644
index 0000000..d3667a8
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryBB.pm
@@ -0,0 +1,40 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::RegistryBB;
+
+use strict;
+use warnings FATAL => 'all';
+
+# we try to develop so we reload ourselves without die'ing on the warning
+no warnings qw(redefine); # XXX, this should go away in production!
+
+our $VERSION = '1.99';
+
+use base qw(ModPerl::RegistryCooker);
+
+sub handler : method {
+ my $class = (@_ >= 2) ? shift : __PACKAGE__;
+ my $r = shift;
+ return $class->new($r)->default_handler();
+}
+
+# currently all the methods are inherited through the normal ISA
+# search may
+
+1;
+__END__
+
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm
new file mode 100644
index 0000000..cf50007
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm
@@ -0,0 +1,788 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# VERY IMPORTANT: Be very careful modifying the defaults, since many
+# VERY IMPORTANT: packages rely on them. In fact you should never
+# VERY IMPORTANT: modify the defaults after the package gets released,
+# VERY IMPORTANT: since they are a hardcoded part of this suite's API.
+
+package ModPerl::RegistryCooker;
+
+require 5.006;
+
+use strict;
+use warnings FATAL => 'all';
+
+our $VERSION = '1.99';
+
+use Apache2::ServerUtil ();
+use Apache2::Response ();
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::RequestIO ();
+use Apache2::Log ();
+use Apache2::Access ();
+
+use APR::Table ();
+use APR::Finfo ();
+use APR::Status ();
+
+use ModPerl::Util ();
+use ModPerl::Global ();
+
+use File::Spec::Functions ();
+use File::Basename ();
+
+use Apache2::Const -compile => qw(:common &OPT_EXECCGI);
+use APR::Const -compile => qw(FILETYPE_REG);
+use ModPerl::Const -compile => 'EXIT';
+
+unless (defined $ModPerl::Registry::MarkLine) {
+ $ModPerl::Registry::MarkLine = 1;
+}
+
+#########################################################################
+# debug constants
+#
+#########################################################################
+use constant D_NONE => 0;
+use constant D_ERROR => 1;
+use constant D_WARN => 2;
+use constant D_COMPILE => 4;
+use constant D_NOISE => 8;
+
+# the debug level can be overriden on the main server level of
+# httpd.conf with:
+# PerlSetVar ModPerl::RegistryCooker::DEBUG 4
+use constant DEBUG => 0;
+#XXX: below currently crashes the server on win32
+# defined Apache2->server->dir_config('ModPerl::RegistryCooker::DEBUG')
+# ? Apache2->server->dir_config('ModPerl::RegistryCooker::DEBUG')
+# : D_NONE;
+
+#########################################################################
+# OS specific constants
+#
+#########################################################################
+use constant IS_WIN32 => $^O eq "MSWin32";
+
+#########################################################################
+# constant subs
+#
+#########################################################################
+use constant NOP => '';
+use constant TRUE => 1;
+use constant FALSE => 0;
+
+
+use constant NAMESPACE_ROOT => 'ModPerl::ROOT';
+
+
+#########################################################################
+
+unless (defined $ModPerl::RegistryCooker::NameWithVirtualHost) {
+ $ModPerl::RegistryCooker::NameWithVirtualHost = 1;
+}
+
+#########################################################################
+# func: new
+# dflt: new
+# args: $class - class to bless into
+# $r - Apache2::RequestRec object
+# desc: create the class's object and bless it
+# rtrn: the newly created object
+#########################################################################
+
+sub new {
+ my ($class, $r) = @_;
+ my $self = bless {}, $class;
+ $self->init($r);
+ return $self;
+}
+
+#########################################################################
+# func: init
+# dflt: init
+# desc: initializes the data object's fields: REQ FILENAME URI
+# args: $r - Apache2::RequestRec object
+# rtrn: nothing
+#########################################################################
+
+sub init {
+ $_[0]->{REQ} = $_[1];
+ $_[0]->{URI} = $_[1]->uri;
+ $_[0]->{FILENAME} = $_[1]->filename;
+}
+
+#########################################################################
+# func: handler
+# dflt: handler
+# desc: the handler() sub that is expected by Apache
+# args: $class - handler's class
+# $r - Apache2::RequestRec object
+# (o)can be called as handler($r) as well (without leading $class)
+# rtrn: handler's response status
+# note: must be implemented in a sub-class unless configured as
+# Apache2::Foo->handler in httpd.conf (because of the
+# __PACKAGE__, which is tied to the file)
+#########################################################################
+
+sub handler : method {
+ my $class = (@_ >= 2) ? shift : __PACKAGE__;
+ my $r = shift;
+ return $class->new($r)->default_handler();
+}
+
+#########################################################################
+# func: default_handler
+# dflt: META: see above
+# desc: META: see above
+# args: $self - registry blessed object
+# rtrn: handler's response status
+# note: that's what most sub-class handlers will call
+#########################################################################
+
+sub default_handler {
+ my $self = shift;
+
+ $self->make_namespace;
+
+ if ($self->should_compile) {
+ my $rc = $self->can_compile;
+ return $rc unless $rc == Apache2::Const::OK;
+ $rc = $self->convert_script_to_compiled_handler;
+ return $rc unless $rc == Apache2::Const::OK;
+ }
+
+ # handlers shouldn't set $r->status but return it, so we reset the
+ # status after running it
+ my $old_status = $self->{REQ}->status;
+ my $rc = $self->run;
+ my $new_status = $self->{REQ}->status($old_status);
+ return ($rc == Apache2::Const::OK && $old_status != $new_status)
+ ? $new_status
+ : $rc;
+}
+
+#########################################################################
+# func: run
+# dflt: run
+# desc: executes the compiled code
+# args: $self - registry blessed object
+# rtrn: execution status (Apache2::?)
+#########################################################################
+
+sub run {
+ my $self = shift;
+
+ my $r = $self->{REQ};
+ my $package = $self->{PACKAGE};
+
+ $self->chdir_file;
+
+ my $cv = \&{"$package\::handler"};
+
+ my %orig_inc;
+ if ($self->should_reset_inc_hash) {
+ %orig_inc = %INC;
+ }
+
+ my $rc = Apache2::Const::OK;
+ { # run the code and preserve warnings setup when it's done
+ no warnings FATAL => 'all';
+ #local $^W = 0;
+ eval { $cv->($r, @_) };
+
+ # log script's execution errors
+ $rc = $self->error_check;
+
+ {
+ # there might be no END blocks to call, so $@ will be not
+ # reset
+ local $@;
+ ModPerl::Global::special_list_call(END => $package);
+
+ # log script's END blocks execution errors
+ my $new_rc = $self->error_check;
+
+ # use the END blocks return status if the script's execution
+ # was successful
+ $rc = $new_rc if $rc == Apache2::Const::OK;
+ }
+
+ }
+
+ if ($self->should_reset_inc_hash) {
+ # to avoid the bite of require'ing a file with no package delaration
+ # Apache2::PerlRun in mod_perl 1.15_01 started to localize %INC
+ # later on it has been adjusted to preserve loaded .pm files,
+ # which presumably contained the package declaration
+ for (keys %INC) {
+ next if $orig_inc{$_};
+ next if /\.pm$/;
+ delete $INC{$_};
+ }
+ }
+
+ $self->flush_namespace;
+
+ $self->chdir_file(Apache2::ServerUtil::server_root());
+
+ return $rc;
+}
+
+
+
+#########################################################################
+# func: can_compile
+# dflt: can_compile
+# desc: checks whether the script is allowed and can be compiled
+# args: $self - registry blessed object
+# rtrn: $rc - return status to forward
+# efct: initializes the data object's fields: MTIME
+#########################################################################
+
+sub can_compile {
+ my $self = shift;
+ my $r = $self->{REQ};
+
+ return Apache2::Const::DECLINED
+ unless $r->finfo->filetype==APR::Const::FILETYPE_REG;
+
+ $self->{MTIME} = $r->finfo->mtime;
+
+ if (!($r->allow_options & Apache2::Const::OPT_EXECCGI)) {
+ $r->log_error("Options ExecCGI is off in this directory",
+ $self->{FILENAME});
+ return Apache2::Const::FORBIDDEN;
+ }
+
+ $self->debug("can compile $self->{FILENAME}") if DEBUG & D_NOISE;
+
+ return Apache2::Const::OK;
+
+}
+#########################################################################
+# func: namespace_root
+# dflt: namespace_root
+# desc: define the namespace root for storing compiled scripts
+# args: $self - registry blessed object
+# rtrn: the namespace root
+#########################################################################
+
+sub namespace_root {
+ my $self = shift;
+ join '::', NAMESPACE_ROOT, ref($self);
+}
+
+#########################################################################
+# func: make_namespace
+# dflt: make_namespace
+# desc: prepares the namespace
+# args: $self - registry blessed object
+# rtrn: the namespace
+# efct: initializes the field: PACKAGE
+#########################################################################
+
+sub make_namespace {
+ my $self = shift;
+
+ my $package = $self->namespace_from;
+
+ # Escape everything into valid perl identifiers
+ $package =~ s/([^A-Za-z0-9_])/sprintf("_%2x", unpack("C", $1))/eg;
+
+ # make sure that the sub-package doesn't start with a digit
+ $package =~ s/^(\d)/_$1/;
+
+ # prepend root
+ $package = $self->namespace_root() . "::$package";
+
+ $self->{PACKAGE} = $package;
+
+ return $package;
+}
+
+#########################################################################
+# func: namespace_from
+# dflt: namespace_from_filename
+# desc: returns a partial raw package name based on filename, uri, else
+# args: $self - registry blessed object
+# rtrn: a unique string
+#########################################################################
+
+*namespace_from = \&namespace_from_filename;
+
+# return a package name based on $r->filename only
+sub namespace_from_filename {
+ my $self = shift;
+
+ my ($volume, $dirs, $file) =
+ File::Spec::Functions::splitpath($self->{FILENAME});
+ my @dirs = File::Spec::Functions::splitdir($dirs);
+ return join '_', grep { defined && length } $volume, @dirs, $file;
+}
+
+# return a package name based on $r->uri only
+sub namespace_from_uri {
+ my $self = shift;
+
+ my $path_info = $self->{REQ}->path_info;
+ my $script_name = $path_info && $self->{URI} =~ /\Q$path_info\E$/
+ ? substr($self->{URI}, 0, length($self->{URI}) - length($path_info))
+ : $self->{URI};
+
+ if ($ModPerl::RegistryCooker::NameWithVirtualHost &&
+ $self->{REQ}->server->is_virtual) {
+ my $name = $self->{REQ}->get_server_name;
+ $script_name = join "", $name, $script_name if $name;
+ }
+
+ $script_name =~ s:/+$:/__INDEX__:;
+
+ return $script_name;
+}
+
+#########################################################################
+# func: convert_script_to_compiled_handler
+# dflt: convert_script_to_compiled_handler
+# desc: reads the script, converts into a handler and compiles it
+# args: $self - registry blessed object
+# rtrn: success/failure status
+#########################################################################
+
+sub convert_script_to_compiled_handler {
+ my $self = shift;
+
+ my $rc = Apache2::Const::OK;
+
+ $self->debug("Adding package $self->{PACKAGE}") if DEBUG & D_NOISE;
+
+ # get the script's source
+ $rc = $self->read_script;
+ return $rc unless $rc == Apache2::Const::OK;
+
+ # convert the shebang line opts into perl code
+ my $shebang = $self->shebang_to_perl;
+
+ # mod_cgi compat, should compile the code while in its dir, so
+ # relative require/open will work.
+ $self->chdir_file;
+
+# undef &{"$self->{PACKAGE}\::handler"}; unless DEBUG & D_NOISE; #avoid warnings
+# $self->{PACKAGE}->can('undef_functions') && $self->{PACKAGE}->undef_functions;
+
+ my $line = $self->get_mark_line;
+
+ $self->strip_end_data_segment;
+
+ # handle the non-parsed handlers ala mod_cgi (though mod_cgi does
+ # some tricks removing the header_out and other filters, here we
+ # just call assbackwards which has the same effect).
+ my $base = File::Basename::basename($self->{FILENAME});
+ my $nph = substr($base, 0, 4) eq 'nph-' ? '$_[0]->assbackwards(1);' : "";
+ my $script_name = $self->get_script_name || $0;
+
+ my $eval = join '',
+ 'package ',
+ $self->{PACKAGE}, ";",
+ "sub handler {",
+ "local \$0 = '$script_name';",
+ $nph,
+ $shebang,
+ $line,
+ ${ $self->{CODE} },
+ "\n}"; # last line comment without newline?
+
+ $rc = $self->compile(\$eval);
+ return $rc unless $rc == Apache2::Const::OK;
+ $self->debug(qq{compiled package \"$self->{PACKAGE}\"}) if DEBUG & D_NOISE;
+
+ $self->chdir_file(Apache2::ServerUtil::server_root());
+
+# if(my $opt = $r->dir_config("PerlRunOnce")) {
+# $r->child_terminate if lc($opt) eq "on";
+# }
+
+ $self->cache_it;
+
+ return $rc;
+}
+
+#########################################################################
+# func: cache_table
+# dflt: cache_table_common
+# desc: return a symbol table for caching compiled scripts in
+# args: $self - registry blessed object (or the class name)
+# rtrn: symbol table
+#########################################################################
+
+*cache_table = \&cache_table_common;
+
+sub cache_table_common {
+ \%ModPerl::RegistryCache;
+}
+
+
+sub cache_table_local {
+ my $self = shift;
+ my $class = ref($self) || $self;
+ no strict 'refs';
+ \%$class;
+}
+
+#########################################################################
+# func: cache_it
+# dflt: cache_it
+# desc: mark the package as cached by storing its modification time
+# args: $self - registry blessed object
+# rtrn: nothing
+#########################################################################
+
+sub cache_it {
+ my $self = shift;
+ $self->cache_table->{ $self->{PACKAGE} }{mtime} = $self->{MTIME};
+}
+
+
+#########################################################################
+# func: is_cached
+# dflt: is_cached
+# desc: checks whether the package is already cached
+# args: $self - registry blessed object
+# rtrn: TRUE if cached,
+# FALSE otherwise
+#########################################################################
+
+sub is_cached {
+ my $self = shift;
+ exists $self->cache_table->{ $self->{PACKAGE} }{mtime};
+}
+
+
+#########################################################################
+# func: should_compile
+# dflt: should_compile_once
+# desc: decide whether code should be compiled or not
+# args: $self - registry blessed object
+# rtrn: TRUE if should compile
+# FALSE otherwise
+# efct: sets MTIME if it's not set yet
+#########################################################################
+
+*should_compile = \&should_compile_once;
+
+# return false only if the package is cached and its source file
+# wasn't modified
+sub should_compile_if_modified {
+ my $self = shift;
+ $self->{MTIME} ||= $self->{REQ}->finfo->mtime;
+ !($self->is_cached &&
+ $self->cache_table->{ $self->{PACKAGE} }{mtime} == $self->{MTIME});
+}
+
+# return false if the package is cached already
+sub should_compile_once {
+ not shift->is_cached;
+}
+
+#########################################################################
+# func: should_reset_inc_hash
+# dflt: FALSE
+# desc: decide whether to localize %INC for required .pl files from the script
+# args: $self - registry blessed object
+# rtrn: TRUE if should reset
+# FALSE otherwise
+#########################################################################
+
+*should_reset_inc_hash = \&FALSE;
+
+#########################################################################
+# func: flush_namespace
+# dflt: NOP (don't flush)
+# desc: flush the compiled package's namespace
+# args: $self - registry blessed object
+# rtrn: nothing
+#########################################################################
+
+*flush_namespace = \&NOP;
+
+sub flush_namespace_normal {
+ my $self = shift;
+
+ $self->debug("flushing namespace") if DEBUG & D_NOISE;
+ ModPerl::Util::unload_package($self->{PACKAGE});
+}
+
+
+#########################################################################
+# func: read_script
+# dflt: read_script
+# desc: reads the script in
+# args: $self - registry blessed object
+# rtrn: Apache2::Const::OK on success, some other code on failure
+# efct: initializes the CODE field with the source script
+#########################################################################
+
+# reads the contents of the file
+sub read_script {
+ my $self = shift;
+
+ $self->debug("reading $self->{FILENAME}") if DEBUG & D_NOISE;
+ $self->{CODE} = eval { $self->{REQ}->slurp_filename(0) }; # untainted
+ if ($@) {
+ $self->log_error("$@");
+
+ if (ref $@ eq 'APR::Error') {
+ return Apache2::Const::FORBIDDEN if APR::Status::is_EACCES($@);
+ return Apache2::Const::NOT_FOUND if APR::Status::is_ENOENT($@);
+ }
+
+ return Apache2::Const::SERVER_ERROR;
+ }
+
+ return Apache2::Const::OK;
+}
+
+#########################################################################
+# func: shebang_to_perl
+# dflt: shebang_to_perl
+# desc: parse the shebang line and convert command line switches
+# (defined in %switches) into a perl code.
+# args: $self - registry blessed object
+# rtrn: a Perl snippet to be put at the beginning of the CODE field
+# by caller
+#########################################################################
+
+my %switches = (
+ 'T' => sub {
+ Apache2::ServerRec::warn("-T switch is ignored, enable " .
+ "with 'PerlSwitches -T' in httpd.conf\n")
+ unless ${^TAINT};
+ "";
+ },
+ 'w' => sub { "use warnings;\n" },
+);
+
+sub shebang_to_perl {
+ my $self = shift;
+ my ($line) = ${ $self->{CODE} } =~ /^(.*)$/m;
+ my @cmdline = split /\s+/, $line;
+ return "" unless @cmdline;
+ return "" unless shift(@cmdline) =~ /^\#!/;
+
+ my $prepend = "";
+ for my $s (@cmdline) {
+ next unless $s =~ s/^-//;
+ last if substr($s,0,1) eq "-";
+ for (split //, $s) {
+ next unless exists $switches{$_};
+ $prepend .= $switches{$_}->();
+ }
+ }
+
+ return $prepend;
+}
+
+#########################################################################
+# func: get_script_name
+# dflt: get_script_name
+# desc: get the script's name to set into $0
+# args: $self - registry blessed object
+# rtrn: path to the script's filename
+#########################################################################
+
+sub get_script_name {
+ shift->{FILENAME};
+}
+
+#########################################################################
+# func: chdir_file
+# dflt: NOP
+# desc: chdirs into $dir
+# args: $self - registry blessed object
+# $dir - a dir
+# rtrn: nothing (?or success/failure?)
+#########################################################################
+
+*chdir_file = \&NOP;
+
+sub chdir_file_normal {
+ my ($self, $dir) = @_;
+ $dir ||= File::Basename::dirname($self->{FILENAME});
+ $self->debug("chdir $dir") if DEBUG & D_NOISE;
+ chdir $dir or die "Can't chdir to $dir: $!";
+}
+
+#########################################################################
+# func: get_mark_line
+# dflt: get_mark_line
+# desc: generates the perl compiler #line directive
+# args: $self - registry blessed object
+# rtrn: returns the perl compiler #line directive
+#########################################################################
+
+sub get_mark_line {
+ my $self = shift;
+ $ModPerl::Registry::MarkLine ? "\n#line 1 $self->{FILENAME}\n" : "";
+}
+
+#########################################################################
+# func: strip_end_data_segment
+# dflt: strip_end_data_segment
+# desc: remove the trailing non-code from $self->{CODE}
+# args: $self - registry blessed object
+# rtrn: nothing
+#########################################################################
+
+sub strip_end_data_segment {
+ ${ +shift->{CODE} } =~ s/^__(END|DATA)__(.*)//ms;
+}
+
+
+
+#########################################################################
+# func: compile
+# dflt: compile
+# desc: compile the code in $eval
+# args: $self - registry blessed object
+# $eval - a ref to a scalar with the code to compile
+# rtrn: success/failure
+# note: $r must not be in scope of compile(), scripts must do
+# my $r = shift; to get it off the args stack
+#########################################################################
+
+sub compile {
+ my ($self, $eval) = @_;
+
+ $self->debug("compiling $self->{FILENAME}") if DEBUG && D_COMPILE;
+
+ ModPerl::Global::special_list_register(END => $self->{PACKAGE});
+ ModPerl::Global::special_list_clear( END => $self->{PACKAGE});
+
+ {
+ # let the code define its own warn and strict level
+ no strict;
+ no warnings FATAL => 'all'; # because we use FATAL
+ eval $$eval;
+ }
+
+ return $self->error_check;
+}
+
+#########################################################################
+# func: error_check
+# dflt: error_check
+# desc: checks $@ for errors
+# args: $self - registry blessed object
+# rtrn: Apache2::Const::SERVER_ERROR if $@ is set, Apache2::Const::OK otherwise
+#########################################################################
+
+sub error_check {
+ my $self = shift;
+
+ # ModPerl::Util::exit() throws an exception object whose rc is
+ # ModPerl::EXIT
+ # (see modperl_perl_exit() and modperl_errsv() C functions)
+ if ($@ && !(ref $@ eq 'APR::Error' && $@ == ModPerl::EXIT)) {
+ $self->log_error($@);
+ return Apache2::Const::SERVER_ERROR;
+ }
+ return Apache2::Const::OK;
+}
+
+
+#########################################################################
+# func: install_aliases
+# dflt: install_aliases
+# desc: install the method aliases into $class
+# args: $class - the class to install the methods into
+# $rh_aliases - a ref to a hash with aliases mapping
+# rtrn: nothing
+#########################################################################
+
+sub install_aliases {
+ my ($class, $rh_aliases) = @_;
+
+ no strict 'refs';
+ while (my ($k,$v) = each %$rh_aliases) {
+ if (my $sub = *{$v}{CODE}){
+ *{ $class . "::$k" } = $sub;
+ }
+ else {
+ die "$class: $k aliasing failed; sub $v doesn't exist";
+ }
+ }
+}
+
+### helper methods
+
+sub debug {
+ my $self = shift;
+ my $class = ref $self;
+ $self->{REQ}->log_error("$$: $class: " . join '', @_);
+}
+
+sub log_error {
+ my ($self, $msg) = @_;
+ my $class = ref $self;
+
+ $self->{REQ}->log_error($msg);
+ $self->{REQ}->notes->set('error-notes' => $msg);
+ $@{$self->{URI}} = $msg;
+}
+
+#########################################################################
+# func: uncache_myself
+# dflt: uncache_myself
+# desc: unmark the package as cached by forgetting its modification time
+# args: none
+# rtrn: nothing
+# note: this is a function and not a method, it should be called from
+# the registry script, and using the caller() method we figure
+# out the package the script was compiled into
+
+#########################################################################
+
+# this is a function should be called from the registry script, and
+# using the caller() method we figure out the package the script was
+# compiled into and trying to uncache it.
+#
+# it's currently used only for testing purposes and not a part of the
+# public interface. it expects to find the compiled package in the
+# symbol table cache returned by cache_table_common(), if you override
+# cache_table() to point to another function, this function will fail.
+sub uncache_myself {
+ my $package = scalar caller;
+ my ($class) = __PACKAGE__->cache_table_common();
+
+ unless (defined $class) {
+ Apache2->warn("$$: cannot figure out cache symbol table for $package");
+ return;
+ }
+
+ if (exists $class->{$package} && exists $class->{$package}{mtime}) {
+ Apache2->warn("$$: uncaching $package\n") if DEBUG & D_COMPILE;
+ delete $class->{$package}{mtime};
+ }
+ else {
+ Apache2->warn("$$: cannot find $package in cache");
+ }
+}
+
+
+1;
+__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryLoader.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryLoader.pm
new file mode 100644
index 0000000..5f03c94
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryLoader.pm
@@ -0,0 +1,168 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::RegistryLoader;
+
+use strict;
+use warnings;
+
+use ModPerl::RegistryCooker ();
+use Apache2::ServerUtil ();
+use Apache2::Log ();
+use APR::Pool ();
+use APR::Finfo ();
+use APR::Const -compile=>qw(FINFO_MIN);
+
+use Carp;
+use File::Spec ();
+
+use Apache2::Const -compile => qw(OK HTTP_OK OPT_EXECCGI);
+
+our @ISA = ();
+
+sub new {
+ my $class = shift;
+ my $self = bless {@_} => ref($class)||$class;
+ $self->{package} ||= 'ModPerl::Registry';
+ $self->{pool} = APR::Pool->new();
+ $self->load_package($self->{package});
+ return $self;
+}
+
+sub handler {
+ my ($self, $uri, $filename, $virthost) = @_;
+
+ # set the inheritance rules at run time
+ @ISA = $self->{package};
+
+ unless (defined $uri) {
+ $self->warn("uri is a required argument");
+ return;
+ }
+
+ if (defined $filename) {
+ unless (-e $filename) {
+ $self->warn("Cannot find: $filename");
+ return;
+ }
+ }
+ else {
+ # try to translate URI->filename
+ if (exists $self->{trans} and ref($self->{trans}) eq 'CODE') {
+ no strict 'refs';
+ $filename = $self->{trans}->($uri);
+ unless (-e $filename) {
+ $self->warn("Cannot find a translated from uri: $filename");
+ return;
+ }
+ }
+ else {
+ # try to guess
+ (my $guess = $uri) =~ s|^/||;
+
+ $self->warn("Trying to guess filename based on uri")
+ if $self->{debug};
+
+ $filename = File::Spec->catfile(Apache2::ServerUtil::server_root,
+ $guess);
+ unless (-e $filename) {
+ $self->warn("Cannot find guessed file: $filename",
+ "provide \$filename or 'trans' sub");
+ return;
+ }
+ }
+ }
+
+ if ($self->{debug}) {
+ $self->warn("*** uri=$uri, filename=$filename");
+ }
+
+ my $rl = bless {
+ uri => $uri,
+ filename => $filename,
+ package => $self->{package},
+ } => ref($self) || $self;
+
+ $rl->{virthost} = $virthost if defined $virthost;
+
+ # can't call SUPER::handler here, because it usually calls new()
+ # and then the ModPerlRegistryLoader::new() will get called,
+ # instead of the super class' new, so we implement the super
+ # class' handler here. Hopefully all other subclasses use the same
+ # handler.
+ __PACKAGE__->SUPER::new($rl)->default_handler();
+
+}
+
+# XXX: s/my_// for qw(my_finfo my_slurp_filename);
+# when when finfo() and slurp_filename() are ported to 2.0 and
+# RegistryCooker is starting to use them
+
+sub get_server_name { return $_[0]->{virthost} if exists $_[0]->{virthost} }
+sub filename { shift->{filename} }
+sub status { Apache2::Const::HTTP_OK }
+sub pool { shift->{pool}||=APR::Pool->new() }
+sub finfo { $_[0]->{finfo}||=APR::Finfo::stat($_[0]->{filename},
+ APR::Const::FINFO_MIN,
+ $_[0]->pool); }
+sub uri { shift->{uri} }
+sub path_info {}
+sub allow_options { Apache2::Const::OPT_EXECCGI } #will be checked again at run-time
+sub log_error { shift; die @_ if $@; warn @_; }
+sub run { return Apache2::Const::OK } # don't run the script
+sub server { shift }
+sub is_virtual { exists shift->{virthost} }
+
+# the preloaded file needs to be precompiled into the package
+# specified by the 'package' attribute, not RegistryLoader
+sub namespace_root {
+ join '::', ModPerl::RegistryCooker::NAMESPACE_ROOT,
+ shift->{REQ}->{package};
+}
+
+# override Apache class methods called by Modperl::Registry*. normally
+# only available at request-time via blessed request_rec pointer
+sub slurp_filename {
+ my $r = shift;
+ my $tainted = @_ ? shift : 1;
+ my $filename = $r->filename;
+ open my $fh, $filename or die "can't open $filename: $!";
+ local $/;
+ my $code = <$fh>;
+ unless ($tainted) {
+ ($code) = $code =~ /(.*)/s; # untaint
+ }
+ close $fh;
+ return \$code;
+}
+
+sub load_package {
+ my ($self, $package) = @_;
+
+ croak "package to load wasn't specified" unless defined $package;
+
+ $package =~ s|::|/|g;
+ $package .= ".pm";
+ require $package;
+};
+
+sub warn {
+ my $self = shift;
+ Apache2::Log->warn(__PACKAGE__ . ": @_\n");
+}
+
+1;
+__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryPrefork.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryPrefork.pm
new file mode 100644
index 0000000..9c41e77
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryPrefork.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package ModPerl::RegistryPrefork;
+
+use strict;
+use warnings FATAL => 'all';
+
+our $VERSION = '0.01';
+
+use base qw(ModPerl::Registry);
+
+if ($ENV{MOD_PERL}) {
+ require Apache2::MPM;
+ die "This package can't be used under threaded MPMs"
+ if Apache2::MPM->is_threaded;
+}
+
+sub handler : method {
+ my $class = (@_ >= 2) ? shift : __PACKAGE__;
+ my $r = shift;
+ return $class->new($r)->default_handler();
+}
+
+*chdir_file = \&ModPerl::RegistryCooker::chdir_file_normal;
+
+1;
+__END__
diff --git a/2_0_13/ModPerl-Registry/t/206.t b/2_0_13/ModPerl-Registry/t/206.t
new file mode 100644
index 0000000..7b72728
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/206.t
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)];
+
+my $url = "/registry/206.pl";
+my $res = GET($url);
+my $body = '<?xml versi';
+
+ok t_cmp(
+ $res->code,
+ 206,
+ "test partial_content: response code",
+);
+
+ok t_cmp(
+ $res->content,
+ $body,
+ "test partial_content: response body",
+);
diff --git a/2_0_13/ModPerl-Registry/t/304.t b/2_0_13/ModPerl-Registry/t/304.t
new file mode 100644
index 0000000..dda87c9
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/304.t
@@ -0,0 +1,63 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 10, need [qw(mod_alias.c HTML::HeadParser)];
+
+my $url = "/registry/304.pl";
+
+{
+ # not modified
+ my $if_modified_since = 'Sun, 29 Oct 2000 15:55:00 GMT';
+ my $res = GET($url, 'If-Modified-Since' => $if_modified_since);
+
+ ok t_cmp(
+ $res->code,
+ 304,
+ "test HTTP_NOT_MODIFIED (304 status)",
+ );
+
+ ok t_cmp(
+ $res->content,
+ '',
+ "test HTTP_NOT_MODIFIED (null body)",
+ );
+
+ #t_debug $res->as_string;
+}
+
+{
+ # full response cases:
+ # 1) the resource has been modified since the If-Modified-Since date
+ # 2) bogus If-Modified-Since date => is considered as a
+ # non-If-Modified-Since require
+ #
+ my %dates = (
+ 'Sun, 29 Oct 2000 15:43:28 GMT' => "the resource was modified since #1",
+ 'Sun, 28 Oct 2000 15:43:29 GMT' => "the resource was modified since #2",
+ 'Thu, 32 Jun 1999 24:59:59 MIT' => "bogus If-Modified-Since #1",
+ 'Thu Juk 99 00:00:00 9999 FUK' => "bogus If-Modified-Since #2",
+ );
+ my $received = '<html><head></head><body>Test</body></html>';
+ while ( my ($if_modified_since, $debug) = each %dates) {
+ my $res = GET($url, 'If-Modified-Since' => $if_modified_since);
+ t_debug "If-Modified-Since $if_modified_since";
+ ok t_cmp(
+ $res->code,
+ 200,
+ "$debug (code)"
+ );
+
+ ok t_cmp(
+ $res->content,
+ $received,
+ "$debug (body)"
+ );
+
+ #t_debug $res->as_string;
+ }
+}
diff --git a/2_0_13/ModPerl-Registry/t/404-filename-with-newline.t b/2_0_13/ModPerl-Registry/t/404-filename-with-newline.t
new file mode 100644
index 0000000..f28710b
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/404-filename-with-newline.t
@@ -0,0 +1,20 @@
+#!perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET_RC);
+
+plan tests => 1, need 'mod_alias.c';
+
+{
+ # this used to result in 500 due to a combination of Perl warning about
+ # a newline in the filename passed to stat() and our
+ # use warnings FATAL=>'all'
+
+ t_client_log_error_is_expected();
+ my $url = '/registry/file%0dwith%0anl%0d%0aand%0a%0dcr';
+ ok t_cmp GET_RC($url), 404, 'URL with \\r and \\n embedded';
+}
diff --git a/2_0_13/ModPerl-Registry/t/404.t b/2_0_13/ModPerl-Registry/t/404.t
new file mode 100644
index 0000000..4b4271a
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/404.t
@@ -0,0 +1,31 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET_BODY GET);
+
+plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)];
+
+{
+ t_client_log_error_is_expected();
+ my $url = "/error_document/cannot_be_found";
+ my $response = "Oops, can't find the requested doc";
+ ok t_cmp(
+ GET_BODY($url),
+ $response,
+ "test ErrorDocument"
+ );
+}
+
+
+{
+ my $url = "/registry/status_change.pl";
+ my $res = GET($url);
+ ok t_cmp(
+ $res->code,
+ 404,
+ "the script has changed the status to 404"
+ );
+}
diff --git a/2_0_13/ModPerl-Registry/t/500.t b/2_0_13/ModPerl-Registry/t/500.t
new file mode 100644
index 0000000..a96e97f
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/500.t
@@ -0,0 +1,91 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 7, need 'mod_alias.c';
+
+{
+ # the script changes the status before the run-time error happens,
+ # this status change should be ignored
+ my $url = "/registry/runtime_error_n_status_change.pl";
+ my $res = GET($url);
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "500 error on runtime error (when the script changes the status)",
+ );
+}
+
+{
+ my $url = "/registry/syntax_error.pl";
+ my $res = GET($url);
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "500 compile time error (syntax error)",
+ );
+}
+
+{
+ my $url = "/registry/use_error.pl";
+ my $res = GET($url);
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "500 compile error on use() failure",
+ );
+}
+
+{
+ my $url = "/registry/missing_headers.pl";
+ my $res = GET($url);
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "500 error on missing HTTP headers",
+ );
+}
+
+{
+ # since we have a runtime error before any body is sent, mod_perl
+ # has a chance to communicate the return status of the script to
+ # Apache before headers are sent, so we get the code 500 in the
+ # HTTP headers
+ my $url = "/registry/runtime_error.pl";
+ my $res = GET($url);
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "500 error on runtime error",
+ );
+}
+
+{
+ # even though we have a runtime error here, the scripts succeeds
+ # to send some body before the error happens and since by that
+ # time Apache has already sent the headers, they will include
+ # 200 OK
+ my $url = "/registry/runtime_error_plus_body.pl";
+ my $res = GET($url);
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 200,
+ "200, followed by a runtime error",
+ );
+
+ # the error message is attached after the body
+ ok t_cmp($res->content,
+ qr/some body.*The server encountered an internal error/ms,
+ "200, followed by a runtime error",
+ );
+}
diff --git a/2_0_13/ModPerl-Registry/t/TEST.PL b/2_0_13/ModPerl-Registry/t/TEST.PL
new file mode 100644
index 0000000..4f82f04
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/TEST.PL
@@ -0,0 +1,56 @@
+use strict;
+use warnings FATAL => 'all';
+
+use FindBin;
+# test against the source lib for easier dev
+use lib "$FindBin::Bin/../lib";
+use lib grep { -d } map "$FindBin::Bin/../../$_", qw(lib Apache-Test/lib);
+
+# pick the common test libs
+use lib "$FindBin::Bin/../../t/lib";
+
+MyTest->new->run(@ARGV);
+
+
+
+# sub-class Apache::TestRunPerl
+package MyTest;
+
+use base qw(Apache::TestRunPerl);
+
+# redirect tests require 2 servers
+use constant MIN_CLIENTS => 2;
+
+use File::Spec::Functions qw(catdir);
+use File::Basename qw(dirname);
+
+use Apache2::Build;
+
+# default timeout in secs (threaded mpms are extremely slow to
+# startup, due to a slow perl_clone operation)
+use constant DEFAULT_STARTUP_TIMEOUT =>
+ Apache2::Build->build_config->mpm_is_threaded() ? 180 : 90;
+
+# subclass new_test_config to add some config vars which will be
+# replaced in generated httpd.conf
+sub new_test_config {
+ my $self = shift;
+
+ require Apache::Test;
+ my $mp2_root_dir = dirname Apache::Test::vars('top_dir');
+ $self->{conf_opts}->{src_dir} = catdir $mp2_root_dir,
+ qw(src modules perl);
+
+ $self->{conf_opts}->{startup_timeout} ||=
+ $ENV{APACHE_TEST_STARTUP_TIMEOUT} ||
+ DEFAULT_STARTUP_TIMEOUT;
+
+ $self->{conf_opts}->{minclients} ||= MIN_CLIENTS;
+
+ return $self->SUPER::new_test_config;
+}
+
+sub bug_report {
+ require ModPerl::TestRun;
+ shift->ModPerl::TestRun::bug_report();
+}
diff --git a/2_0_13/ModPerl-Registry/t/bad_scripts.t b/2_0_13/ModPerl-Registry/t/bad_scripts.t
new file mode 100644
index 0000000..8135484
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/bad_scripts.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 1, need 'mod_alias.c';
+
+{
+ t_client_log_error_is_expected();
+ my $url = "/perlrun/r_inherited.pl";
+ my $res = GET($url);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "the script hasn't declared its private \$r",
+ );
+}
diff --git a/2_0_13/ModPerl-Registry/t/basic.t b/2_0_13/ModPerl-Registry/t/basic.t
new file mode 100644
index 0000000..dcdc174
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/basic.t
@@ -0,0 +1,120 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil qw(t_cmp t_catfile_apache t_client_log_error_is_expected);
+use Apache::TestRequest;
+use Apache::TestConfig ();
+
+my %modules = (
+ registry => 'ModPerl::Registry',
+ registry_bb => 'ModPerl::RegistryBB',
+ perlrun => 'ModPerl::PerlRun',
+);
+
+my @aliases = sort keys %modules;
+
+plan tests => @aliases * 5 + 3, need 'mod_alias.c';
+
+my $vars = Apache::Test::config()->{vars};
+my $script_file = t_catfile_apache $vars->{serverroot}, 'cgi-bin', 'basic.pl';
+
+# very basic compilation/response test
+for my $alias (@aliases) {
+ my $url = "/$alias/basic.pl";
+
+ ok t_cmp(
+ GET_BODY($url),
+ "ok $script_file",
+ "$modules{$alias} basic cgi test",
+ );
+}
+
+# test non-executable bit (it should be executed w/o a problem)
+for my $alias (@aliases) {
+ if (Apache::TestConfig::WIN32) {
+ skip "non-executable bit test for Win32", 0;
+ next;
+ }
+ my $url = "/$alias/not_executable.pl";
+
+ t_client_log_error_is_expected();
+ ok t_cmp(
+ HEAD($url)->code,
+ 200,
+ "$modules{$alias} non-executable file",
+ );
+}
+
+# test environment pre-set
+for my $alias (@aliases) {
+ my $url = "/$alias/env.pl?foo=bar";
+
+ ok t_cmp(
+ GET_BODY($url),
+ "foo=bar",
+ "$modules{$alias} mod_cgi-like environment pre-set",
+ );
+}
+
+# require (actually chdir test)
+for my $alias (@aliases) {
+ my $url = "/$alias/require.pl";
+
+ ok t_cmp(
+ GET_BODY($url),
+ "it works",
+ "$modules{$alias} mod_cgi-like environment pre-set",
+ );
+}
+
+
+# exit
+for my $alias (@aliases) {
+ my $url = "/$alias/exit.pl";
+
+ ok t_cmp(
+ GET_BODY_ASSERT($url),
+ "before exit",
+ "$modules{$alias} mod_cgi-like environment pre-set",
+ );
+}
+
+
+
+# test method handlers
+{
+ my $url = "/registry_oo_conf/env.pl?foo=bar";
+ ok t_cmp(
+ GET_BODY($url),
+ "foo=bar",
+ "ModPerl::Registry->handler mod_cgi-like environment pre-set",
+ );
+}
+
+# test mod_perl api usage
+{
+ my $url = "/registry/content_type.pl";
+ ok t_cmp(
+ GET_BODY($url),
+ "ok",
+ "\$r->content_type('text/plain')",
+ );
+}
+
+
+# test that files with .html extension, which are configured to run as
+# scripts get the headerparse stage working: the default mime handler
+# sets $r->content_type for .html files, so we can't rely on
+# content_type not being set in making the decision whether to parse
+# headers or not
+{
+ my $url = "/registry/send_headers.html";
+ my $res = GET $url;
+ ok t_cmp(
+ $res->content_type,
+ "text/plain",
+ "script's content-type",
+ );
+}
diff --git a/2_0_13/ModPerl-Registry/t/bin_resp.t b/2_0_13/ModPerl-Registry/t/bin_resp.t
new file mode 100644
index 0000000..5ffd780
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/bin_resp.t
@@ -0,0 +1,31 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# testing various binary responses
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 2, need 'mod_alias.c';
+
+# 2 sub-tests
+{
+ # favicon.ico and other .ico image/x-icon images start with
+ # sequence:
+ my $expected = "\000\000\001\000";
+ my $location = "/registry/bin_resp_start_0.pl";
+ #my $location = "/cgi-bin/bin_resp_start_0.pl";
+
+ my $received = GET_BODY_ASSERT $location;
+
+ #t_debug "$received";
+
+ ok t_cmp(length($received), length($expected), "image size");
+
+ t_debug "comparing the binary contents";
+ ok $expected eq $received;
+}
+
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/206.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/206.pl
new file mode 100755
index 0000000..0aeac2b
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/206.pl
@@ -0,0 +1,11 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+ print <<_OUT_;
+Status: 206 Partial Content
+Content-Type: text/html; charset=UTF-8
+Content-Length: 11
+Content-Range: bytes 0-10/1336
+Date: Fri, 31 Jan 2003 09:39:01 GMT
+ETag: "xxxx"
+
+_OUT_
+print '<?xml versi';
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/304.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/304.pl
new file mode 100755
index 0000000..8238112
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/304.pl
@@ -0,0 +1,50 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# manually handle 'If-Modified-Since' requests
+
+use APR::Date ();
+use Apache2::Util ();
+use Apache2::RequestRec ();
+
+use constant FMT => '%a, %d %b %Y %H:%M:%S %Z';
+use constant GMT => 1;
+use Apache2::Const -compile => qw(HTTP_NOT_MODIFIED);
+
+my $last_modified = "Sun, 29 Oct 2000 15:43:29 GMT";
+
+my $r = shift;
+
+my $if_modified_since = $r->headers_in->{'If-Modified-Since'};
+
+my $status = 200;
+my $body = '<html><head></head><body>Test</body></html>';
+
+#APR::Date::parse_http may fail
+my $if_modified_since_secs =
+ ($if_modified_since && APR::Date::parse_http($if_modified_since)) || 0;
+my $last_modified_secs = APR::Date::parse_http($last_modified);
+
+#warn "If-Modified-Since $if_modified_since\n";
+#warn "last_modified_secs $last_modified_secs\n";
+#warn "if_modified_since_secs $if_modified_since_secs\n\n";
+
+if ($last_modified_secs < $if_modified_since_secs) {
+ $status = Apache2::Const::HTTP_NOT_MODIFIED;
+ $body = '';
+}
+
+my $date = Apache2::Util::ht_time($r->pool, $r->request_time, FMT, GMT);
+
+print <<HEADERS;
+Status: $status
+Date: $date
+Server: Apache/2.0.47
+Connection: close
+Last-Modified: $last_modified
+Content-Type: text/html; charset=iso-8859-1
+
+HEADERS
+
+print $body if length $body;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/404.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/404.pl
new file mode 100755
index 0000000..ec1314f
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/404.pl
@@ -0,0 +1,7 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings;
+
+my $r = shift;
+$r->content_type('text/plain');
+print "Oops, can't find the requested doc";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/basic.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/basic.pl
new file mode 100755
index 0000000..2176f3c
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/basic.pl
@@ -0,0 +1,16 @@
+#!perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# test all the basic functionality
+
+print "Content-type: text/plain\n\n";
+
+# test that __END__ can appear in a comment w/o cutting data after it
+
+print "ok $0";
+
+# test that __END__ starting at the beginning of the line makes
+# everything following it, stripped
+__END__
+
+this is some irrelevant data
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/bin_resp_start_0.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/bin_resp_start_0.pl
new file mode 100755
index 0000000..4734b84
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/bin_resp_start_0.pl
@@ -0,0 +1,14 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+
+# favicon.ico and other .ico image/x-icon images start with this sequence
+my $response = "\000\000\001\000";
+
+# test here that the cgi header parser doesn't get confused and decide
+# that there is no response body if it starts with \000 sequence
+
+print "Content-type: image/x-icon\n\n";
+print $response;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/cgi.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/cgi.pl
new file mode 100755
index 0000000..ef4941c
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/cgi.pl
@@ -0,0 +1,5 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use CGI qw/:standard :html3/;
+
+print header(-type=>'text/html');
+print b("done");
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/closure.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/closure.pl
new file mode 100755
index 0000000..495dd7a
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/closure.pl
@@ -0,0 +1,23 @@
+#!perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+BEGIN {
+ use Apache::TestUtil qw/t_server_log_warn_is_expected/;
+ t_server_log_warn_is_expected();
+}
+
+# this script will suffer from a closure problem under registry
+# should see it under ::Registry
+# should not see it under ::PerlRun
+
+print "Content-type: text/plain\n\n";
+
+# this is a closure (when compiled inside handler()):
+my $counter = 0;
+counter();
+
+sub counter {
+ #warn "$$: counter=$counter";
+ print ++$counter;
+}
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/content_type.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/content_type.pl
new file mode 100755
index 0000000..ceb3678
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/content_type.pl
@@ -0,0 +1,4 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+my $r = shift;
+$r->content_type('text/plain');
+$r->print('ok');
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/env.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/env.pl
new file mode 100755
index 0000000..d5990c5
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/env.pl
@@ -0,0 +1,7 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# test env vars
+
+print "Content-type: text/plain\n\n";
+print exists $ENV{QUERY_STRING} && $ENV{QUERY_STRING};
+
+__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/env_val.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/env_val.pl
new file mode 100755
index 0000000..5632183
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/env_val.pl
@@ -0,0 +1,8 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# test env vars
+
+print "Content-type: text/plain\n\n";
+my $var = $ENV{QUERY_STRING};
+print exists $ENV{$var} && $ENV{$var};
+
+__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/exit.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/exit.pl
new file mode 100755
index 0000000..90810ca
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/exit.pl
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# XXX: exit should work by stopping the script, but not quitting the
+# interpreter, though it's not trivial to make an automated test since
+# what you really want to check whether the process didn't quit after
+# exit was called. Things become more complicated with
+# ithreads-enabled perls where one process may have many interpreters
+# and you can't really track those at the moment. So this test needs
+# more work.
+
+print "Content-type: text/plain\n\n";
+
+print "before exit";
+
+exit;
+
+print "after exit";
+
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/flush.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/flush.pl
new file mode 100755
index 0000000..b21f2cb
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/flush.pl
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+local $| = 1; # unbuffered mode
+
+my $r = shift;
+
+print "Content-Type: text/html\n\n";
+print "yet another boring test string";
+
+# This line passes a bucket brigade with a single bucket FLUSH
+# it was causing problems in the mod_deflate filter which was trying to
+# deflate empty output buffer, (the previous print has already flushed
+# all the output) (the fix in mod_deflate.c was to check whether the
+# buffer is full)
+print "";
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/ithreads_io_n_tie.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/ithreads_io_n_tie.pl
new file mode 100755
index 0000000..50d5f71
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/ithreads_io_n_tie.pl
@@ -0,0 +1,87 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+#
+# there is a problem when STDOUT is internally opened to an
+# Apache2::PerlIO layer is cloned on a new thread start. PerlIO_clone
+# in perl_clone() is called too early, before PL_defstash is
+# cloned. As PerlIO_clone calls PerlIOApache_getarg, which calls
+# gv_fetchpv via sv_setref_pv and boom the segfault happens.
+#
+# at the moment we should either not use an internally opened to
+# :Apache2 streams, so the config must be:
+#
+# SetHandler modperl
+#
+# and then either use $r->print("foo") or tie *STDOUT, $r + print "foo"
+#
+# or close and re-open STDOUT to :Apache2 *after* the thread was spawned
+#
+# the above discussion equally applies to STDIN
+#
+# XXX: ->join calls leak under registry, this doesn't happen in the
+# non-registry tests.
+
+use threads;
+
+my $r = shift;
+$r->print("Content-type: text/plain\n\n");
+
+{
+ # now we can use $r->print API:
+ my $thr = threads->new(
+ sub {
+ my $id = shift;
+ $r->print("thread $id\n");
+ return 1;
+ }, 1);
+ # $thr->join; # XXX: leaks scalar
+}
+
+{
+ # close and re-open STDOUT to :Apache2 *after* the thread was
+ # spawned
+ my $thr = threads->new(
+ sub {
+ my $id = shift;
+ close STDOUT;
+ open STDOUT, ">:Apache2", $r
+ or die "can't open STDOUT via :Apache2 layer : $!";
+ print "thread $id\n";
+ return 1;
+ }, 2);
+ # $thr->join; # XXX: leaks scalar
+}
+
+{
+ # tie STDOUT to $r *after* the ithread was started has
+ # happened, in which case we can use print
+ my $thr = threads->new(
+ sub {
+ my $id = shift;
+ tie *STDOUT, $r;
+ print "thread $id\n";
+ return 1;
+ }, 3);
+ # $thr->join; # XXX: leaks scalar
+}
+
+{
+ # tie STDOUT to $r before the ithread was started has
+ # happened, in which case we can use print
+ tie *STDOUT, $r;
+ my $thr = threads->new(
+ sub {
+ my $id = shift;
+ print "thread $id\n";
+ return 1;
+ }, 4);
+ # $thr->join; # XXX: leaks scalar
+}
+
+sleep 2; # XXX: will go away ones join() calls are enabled
+
+print "parent\n";
+
+untie *STDOUT; # don't affect other tests
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/local-conf.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/local-conf.pl
new file mode 100644
index 0000000..e4e8dc9
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/local-conf.pl
@@ -0,0 +1,4 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+$test_require = 'it works';
+
+1;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/missing_headers.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/missing_headers.pl
new file mode 100755
index 0000000..5dad82d
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/missing_headers.pl
@@ -0,0 +1,9 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+BEGIN {
+ use Apache::TestUtil;
+ t_server_log_error_is_expected();
+}
+print "No HTTP headers were sent\n\n";
+
+print "Here is some more body coming\n even with double new line\n\n";
+print "Here is some more body coming";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/not_executable.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/not_executable.pl
new file mode 100644
index 0000000..d9ed3ba
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/not_executable.pl
@@ -0,0 +1,11 @@
+#!perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# this test should return forbidden, since it should be not-executable
+
+print "Content-type: text/plain\n\n";
+print "ok";
+
+__END__
+
+this is some irrelevant data
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/nph-foo.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/nph-foo.pl
new file mode 100755
index 0000000..a46836a
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/nph-foo.pl
@@ -0,0 +1,14 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+my $r = shift;
+
+print "HTTP/1.0 250 Pretty OK\r\n";
+print join("\n",
+ 'Content-type: text/text',
+ 'Pragma: no-cache',
+ 'Cache-control: must-revalidate, no-cache, no-store',
+ 'Expires: -1',
+ "\n");
+
+print "non-parsed headers body";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_decl.pm b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_decl.pm
new file mode 100644
index 0000000..748b1af
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_decl.pm
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package perlrun_decl;
+
+use warnings;
+use strict;
+
+use base qw(Exporter);
+our @EXPORT = qw(decl_proto);
+
+# this BEGIN block is called only once, since this module doesn't get
+# removed from %INC after it was loaded
+BEGIN {
+ # use an external package which will persist across requests
+ $MyData::blocks{perlrun_decl}++;
+}
+
+sub decl_proto ($;$) { shift }
+
+# this END block won't be executed until the server shutdown
+END {
+ $MyData::blocks{perlrun_decl}--;
+}
+
+1;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_extload.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_extload.pl
new file mode 100755
index 0000000..72269de
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_extload.pl
@@ -0,0 +1,62 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use warnings;
+use strict;
+
+use Apache::Test ();
+use Apache::TestUtil;
+use File::Spec::Functions qw(catfile catdir);
+
+use lib catdir Apache::Test::vars('serverroot'), 'cgi-bin';
+my $require = catfile Apache::Test::vars('serverroot'),
+ qw(cgi-bin perlrun_nondecl.pl);
+
+print "Content-type: text/plain\n\n";
+
+### declared package module ###
+{
+ # require a module w/ package declaration (it doesn't get reloaded
+ # because it declares the package). But we still have a problem with
+ # subs declaring prototypes. When perlrun_decl->import is called, the
+ # original function's prototype doesn't match the aliases prototype.
+ # see decl_proto()
+ BEGIN { t_server_log_warn_is_expected()
+ if perlrun_decl->can("decl_proto");
+ }
+ use perlrun_decl;
+
+ die "perlrun_decl BEGIN block was run more than once"
+ if $MyData::blocks{perlrun_decl} > 1;
+
+ print "d";
+ print decl_proto(1);
+}
+
+### non-declared package module ###
+{
+ # how many times were were called from the same interpreter
+ $MyData::blocks{cycle}{perlrun_nondecl}++;
+ $MyData::blocks{BEGIN}{perlrun_nondecl} ||= 0;
+ $MyData::blocks{END} {perlrun_nondecl} ||= 0;
+
+ # require a lib w/o package declaration. Functions in that lib get
+ # automatically aliased to the functions in the current package.
+ require "$require";
+
+ die "perlrun_nondecl's BEGIN block wasn't run"
+ if $MyData::blocks{BEGIN}{perlrun_nondecl} !=
+ $MyData::blocks{cycle}{perlrun_nondecl};
+
+ # the END block for this cycle didn't run yet, but we can test the
+ # previous cycle's one
+ die "perlrun_nondecl's END block wasn't run"
+ if $MyData::blocks{END}{perlrun_nondecl} + 1 !=
+ $MyData::blocks{cycle}{perlrun_nondecl};
+
+ # they all get redefined warning inside perlrun_nondecl.pl, since that
+ # lib loads it into main::, vs. PerlRun undefs the current __PACKAGE__
+ print "nd";
+ print nondecl_no_proto();
+ print nondecl_proto(2);
+ print nondecl_proto_empty("whatever");
+ print nondecl_const();
+}
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_nondecl.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_nondecl.pl
new file mode 100644
index 0000000..da36515
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_nondecl.pl
@@ -0,0 +1,56 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# we use this file to test how the files w/o package declaration,
+# required from perlrun, work
+
+use Apache::TestUtil;
+
+my $num;
+
+# this BEGIN block is called on every request, since this file gets
+# removed from %INC after it was loaded
+BEGIN {
+ # use an external package which will persist across requests
+ $MyData::blocks{BEGIN}{perlrun_nondecl}++;
+}
+
+use subs qw(warn_exp);
+
+# all subs in this file get 'redefined' warning because they are
+# reloaded in the main:: package, which is not under PerlRun's
+# control.
+
+BEGIN {
+ t_server_log_warn_is_expected()
+ if defined *{"nondecl_no_proto"}{CODE};
+}
+# normal sub, no prototype
+sub nondecl_no_proto { 1 }
+
+BEGIN {
+ t_server_log_warn_is_expected()
+ if defined *{"nondecl_proto"}{CODE};
+}
+# sub with a scalar proto
+sub nondecl_proto ($) { $num = shift }
+
+BEGIN {
+ t_server_log_warn_is_expected()
+ if defined *{"nondecl_proto_empty"}{CODE};
+}
+# sub with an empty proto, but not a constant
+sub nondecl_proto_empty () { $num + 1 }
+
+# besides the the constant sub will generate two warnings for nondecl_const:
+# - one for main::
+# - another for perlrun's virtual package
+BEGIN {
+ t_server_log_warn_is_expected(2);
+}
+# a constant.
+sub nondecl_const () { 4 }
+
+END {
+ $MyData::blocks{END}{perlrun_nondecl}++;
+}
+
+1;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/prefork.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/prefork.pl
new file mode 100755
index 0000000..ae66b87
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/prefork.pl
@@ -0,0 +1,20 @@
+#!perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# test that prefork runs from the directory the script lives in
+
+# All Modperl::*Prefork modules must chdir into the current dir, so we
+# should be able to read ourselves via a relative path
+
+print "Content-type: text/plain\n\n";
+
+my $script = "prefork.pl";
+if (open my $fh, $script) {
+ print "ok $script";
+}
+else {
+ print "prefork didn't chdir into the scripts directory?";
+ print " The error was: $!";
+}
+
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/r_inherited.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/r_inherited.pl
new file mode 100755
index 0000000..a6eee27
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/r_inherited.pl
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings;
+
+# this script shouldn't work
+
+# this is to test that $r is not in the scope from the function that
+# has compiled this script in the registry module
+
+# my $r = shift;
+
+$r->content_type('text/plain');
+$r->print($r->args);
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/redirect-cookie.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect-cookie.pl
new file mode 100755
index 0000000..41fd912
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect-cookie.pl
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# test env vars
+
+use Apache2::URI ();
+use Apache2::Const -compile => qw(REDIRECT SERVER_ERROR);
+
+my $r = shift;
+my $path = $r->args || '';
+$server = $r->construct_server;
+
+$r->err_headers_out->set('Set-Cookie' => "mod_perl=ubercool; path=/");
+$r->headers_out->set(Location => " http://$server$path");
+$r->status(Apache2::Const::REDIRECT);
+
+# exit status is completely ignored in Registry
+# due to $r->status hacking
+return Apache2::Const::SERVER_ERROR;
+
+__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/redirect.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect.pl
new file mode 100755
index 0000000..7c92679
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect.pl
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# test env vars
+
+use Apache2::URI ();
+
+my $r = shift;
+my $path = $r->args || '';
+$server = $r->construct_server;
+
+print "Location: http://$server$path\n\n";
+#warn "Location: http://$server$path\n\n";
+
+__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/require.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/require.pl
new file mode 100755
index 0000000..43bd7eb
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/require.pl
@@ -0,0 +1,17 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# test the require
+
+use Apache::Test ();
+use File::Spec::Functions qw(catfile);
+
+my $vars = Apache::Test::config()->{vars};
+my $require = catfile $vars->{serverroot}, 'cgi-bin', 'local-conf.pl';
+
+print "Content-type: text/plain\n\n";
+
+# XXX: meanwhile we don't chdir to the script's dir
+delete $INC{$require};
+require $require;
+
+print defined $test_require && $test_require;
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error.pl
new file mode 100755
index 0000000..9cf74a1
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error.pl
@@ -0,0 +1,11 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+BEGIN {
+ use Apache::TestUtil;
+ t_server_log_error_is_expected();
+}
+
+# this script sends no body at all, and since the error happens
+# the script will return 500
+
+print "Content-type: text/plain\n\n";
+print no_such_func();
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_n_status_change.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_n_status_change.pl
new file mode 100755
index 0000000..1687d2d
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_n_status_change.pl
@@ -0,0 +1,12 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+BEGIN {
+ use Apache::TestUtil;
+ t_server_log_error_is_expected();
+}
+
+use Apache2::Const -compile => qw(NOT_FOUND);
+
+my $r = shift;
+$r->status(Apache2::Const::NOT_FOUND);
+$r->print("Content-type: text/plain\n\n");
+$r->print(no_such_func());
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_plus_body.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_plus_body.pl
new file mode 100755
index 0000000..c53f5dd
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_plus_body.pl
@@ -0,0 +1,11 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+BEGIN {
+ use Apache::TestUtil;
+ t_server_log_error_is_expected();
+}
+
+# this script sends some body before the error happens,
+# so 200 OK is expected, followed by an error
+print "Content-type: text/plain\n\n";
+print "some body";
+print no_such_func();
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/send_headers.html b/2_0_13/ModPerl-Registry/t/cgi-bin/send_headers.html
new file mode 100755
index 0000000..1c35576
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/send_headers.html
@@ -0,0 +1,3 @@
+print "Content-type: text/plain\n\n";
+print "ok";
+
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/special_blocks.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/special_blocks.pl
new file mode 100755
index 0000000..d1d66f9
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/special_blocks.pl
@@ -0,0 +1,35 @@
+#!perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# test BEGIN/END blocks
+
+use Apache2::RequestRec ();
+
+use vars qw($query);
+$query = '' unless defined $query;
+
+BEGIN {
+ $query = $ENV{QUERY_STRING};
+}
+
+print "Content-type: text/plain\n\n";
+
+my $r = shift;
+our $test = $r->args || '';
+
+if ($test eq 'uncache') {
+ # mark the script as non-cached for the next execution
+ require ModPerl::RegistryCooker;
+ ModPerl::RegistryCooker::uncache_myself();
+}
+elsif ($test eq 'begin') {
+ print "begin ok" if $query eq 'begin';
+ # reset the global
+ $query = '';
+}
+
+END {
+ if (defined $test && $test eq 'end') {
+ print "end ok";
+ }
+}
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/status_change.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/status_change.pl
new file mode 100755
index 0000000..4475d5a
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/status_change.pl
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache2::Const -compile => qw(NOT_FOUND);
+
+my $r = shift;
+$r->status(Apache2::Const::NOT_FOUND);
+$r->print("Content-type: text/plain\n\n");
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/syntax_error.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/syntax_error.pl
new file mode 100755
index 0000000..1716354
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/syntax_error.pl
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+BEGIN {
+ use Apache::TestUtil;
+ t_server_log_error_is_expected();
+}
+
+print "Content-type: text/plain\n\n";
+
+# the following syntax error is here on purpose!
+
+lkj;\;
+
+print "done";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/use_error.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/use_error.pl
new file mode 100755
index 0000000..00188c8
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi-bin/use_error.pl
@@ -0,0 +1,10 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+BEGIN {
+ use Apache::TestUtil;
+ t_server_log_error_is_expected();
+}
+
+use DoesNotExist ();
+
+print "Content-type: text/plain\n\n";
+print "this script is expected to fail";
diff --git a/2_0_13/ModPerl-Registry/t/cgi.t b/2_0_13/ModPerl-Registry/t/cgi.t
new file mode 100644
index 0000000..b9133c5
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/cgi.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)],
+ need_min_module_version CGI => 3.08;
+
+my $url = "/registry/cgi.pl";
+my $res = GET $url;
+
+ok t_cmp($res->header('Content-type'),
+ qr{^text/html},
+ "test 'Content-type header setting");
+
+ok t_cmp(lc($res->content),
+ '<b>done</b>',
+ "test body");
diff --git a/2_0_13/ModPerl-Registry/t/closure.t b/2_0_13/ModPerl-Registry/t/closure.t
new file mode 100644
index 0000000..dad160f
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/closure.t
@@ -0,0 +1,146 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use TestCommon::SameInterp;
+
+use File::Spec::Functions;
+
+# this test tests how various registry packages cache and flush the
+# scripts their run, and whether they check modification on the disk
+# or not. We don't test the closure side effect, but we use it as a
+# test aid. The tests makes sure that they run through the same
+# interpreter all the time (in case that the server is running more
+# than one interpreter)
+
+my @modules = qw(registry registry_bb perlrun);
+
+plan tests => 6, need [qw(mod_alias.c HTML::HeadParser)];
+
+my $cfg = Apache::Test::config();
+
+my $file = 'closure.pl';
+my $path = catfile $cfg->{vars}->{serverroot}, 'cgi-bin', $file;
+my $orig_mtime = (stat($path))[8];
+
+# for all sub-tests in this test, we make sure that we always get onto
+# the same interpreter. if this doesn't happen we skip the sub-test or
+# a group of them, where several sub-tests rely on each other.
+
+{
+ # ModPerl::PerlRun
+ # always flush
+ # no cache
+
+ my $url = "/same_interp/perlrun/$file";
+ my $same_interp = Apache::TestRequest::same_interp_tie($url);
+
+ # should be no closure effect, always returns 1
+ my $first = same_interp_req_body($same_interp, \&GET, $url);
+ my $second = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ (scalar(grep defined, $first, $second) != 2),
+ $first && $second && ($second - $first),
+ 0,
+ "never the closure problem",
+ );
+
+ # modify the file
+ touch_mtime($path);
+
+ # it doesn't matter, since the script is not cached anyway
+ my $third = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ (scalar(grep defined, $first, $second, $third) != 3),
+ $third,
+ 1,
+ "never the closure problem",
+ );
+
+ reset_mtime($path);
+}
+
+{
+ # ModPerl::Registry
+ # no flush
+ # cache, but reload on modification
+ my $url = "/same_interp/registry/$file";
+ my $same_interp = Apache::TestRequest::same_interp_tie($url);
+
+ # we don't know what other test has called this uri before, so we
+ # check the difference between two subsequent calls. In this case
+ # the difference should be 1.
+ my $first = same_interp_req_body($same_interp, \&GET, $url);
+ my $second = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ (scalar(grep defined, $first, $second) != 2),
+ $first && $second && ($second - $first),
+ 1,
+ "the closure problem should exist",
+ );
+
+ # modify the file
+ touch_mtime($path);
+
+ # should not notice closure effect on the first request
+ my $third = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ (scalar(grep defined, $first, $second, $third) != 3),
+ $third,
+ 1,
+ "no closure on the first request",
+ );
+
+ reset_mtime($path);
+}
+
+{
+ # ModPerl::RegistryBB
+ # no flush
+ # cache once, don't check for mods
+ my $url = "/same_interp/registry_bb/$file";
+ my $same_interp = Apache::TestRequest::same_interp_tie($url);
+
+ # we don't know what other test has called this uri before, so we
+ # check the difference between two subsequent calls. In this case
+ # the difference should be 1.
+ my $first = same_interp_req_body($same_interp, \&GET, $url);
+ my $second = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ (scalar(grep defined, $first, $second) != 2),
+ $first && $second && ($second - $first),
+ 1,
+ "the closure problem should exist",
+ );
+
+ # modify the file
+ touch_mtime($path);
+
+ # modification shouldn't be noticed
+ my $third = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ (scalar(grep defined, $first, $second, $third) != 3),
+ $first && $second && $third - $second,
+ 1,
+ "no reload on modification, the closure problem persists",
+ );
+
+ reset_mtime($path);
+}
+
+sub touch_mtime {
+ my $file = shift;
+ # push the mtime into the future (at least 2 secs to work on win32)
+ # so ModPerl::Registry will re-compile the package
+ my $time = time + 5; # make it 5 to be sure
+ utime $time, $time, $file;
+}
+
+sub reset_mtime {
+ my $file = shift;
+ # reset the timestamp to the original mod-time
+ utime $orig_mtime, $orig_mtime, $file;
+}
diff --git a/2_0_13/ModPerl-Registry/t/conf/extra.conf.in b/2_0_13/ModPerl-Registry/t/conf/extra.conf.in
new file mode 100644
index 0000000..1bdf835
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/conf/extra.conf.in
@@ -0,0 +1,235 @@
+#this file will be Include-d by @ServerRoot@/httpd.conf
+
+# Adjust PerlInterpMax and PerlInterpMaxSpare if the requirements change
+# at the moment all tests require only 1 interprter
+<IfDefine PERL_USEITHREADS>
+ PerlInterpStart 1
+ PerlInterpMax 1
+ PerlInterpMinSpare 1
+ PerlInterpMaxSpare 1
+</IfDefine>
+
+# make sure that we test under Taint and warnings mode enabled
+PerlSwitches -wT
+
+PerlSwitches -I@ServerRoot@/../lib \
+ -I@ServerRoot@/../../Apache-Test/lib \
+ -I@ServerRoot@/../../lib \
+ -I@ServerRoot@/../../blib/lib \
+ -I@ServerRoot@/../../blib/arch
+
+# run on startup
+PerlRequire @ServerRoot@/conf/modperl_extra_startup.pl
+
+PerlSetVar ModPerl::RegistryCooker::DEBUG 2
+
+PerlModule ModPerl::RegistryCooker
+PerlModule ModPerl::Util
+
+#############################
+### Normal registry setup ###
+#############################
+<IfModule mod_alias.c>
+ Alias /registry/ @ServerRoot@/cgi-bin/
+ Alias /dirindex/ @ServerRoot@/cgi-bin/
+ Alias /registry_bb/ @ServerRoot@/cgi-bin/
+ Alias /registry_oo_conf/ @ServerRoot@/cgi-bin/
+ Alias /registry_prefork/ @ServerRoot@/cgi-bin/
+ Alias /perlrun/ @ServerRoot@/cgi-bin/
+ Alias /perlrun_prefork/ @ServerRoot@/cgi-bin/
+ Alias /nph/ @ServerRoot@/cgi-bin/
+ Alias /registry_modperl_handler/ @ServerRoot@/cgi-bin/
+ Alias /rewrite_env/ @ServerRoot@/cgi-bin/
+
+ ScriptAlias /cgi-bin/ @ServerRoot@/cgi-bin/
+</IfModule>
+
+PerlModule ModPerl::RegistryBB
+<Location /registry_bb>
+ PerlOptions +GlobalRequest
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::RegistryBB
+ PerlOptions +ParseHeaders
+</Location>
+
+PerlModule ModPerl::Registry
+<Location /registry>
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::Registry
+ PerlOptions +ParseHeaders
+</Location>
+
+<IfModule mod_dir.c>
+ <Location /dirindex>
+ AddHandler perl-script .pl
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::Registry
+ PerlOptions +ParseHeaders
+ DirectoryIndex cgi.pl
+ </Location>
+</IfModule>
+
+<Location /registry_modperl_handler>
+ SetHandler modperl
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::Registry
+ PerlOptions +ParseHeaders
+</Location>
+
+<Location /registry_oo_conf>
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::Registry->handler
+ PerlOptions +ParseHeaders
+</Location>
+
+<Location /nph>
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::Registry
+</Location>
+
+# don't preload ModPerl::RegistryPrefork as it won't load under
+# threaded MPMs
+<Location /registry_prefork>
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::RegistryPrefork
+ PerlOptions +ParseHeaders
+</Location>
+
+# don't preload ModPerl::PerlRunPrefork as it won't load under
+# threaded MPMs
+<Location /perlrun_prefork>
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::PerlRunPrefork
+ PerlOptions +ParseHeaders
+</Location>
+
+PerlModule ModPerl::PerlRun
+<Location /perlrun>
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::PerlRun
+ PerlOptions +ParseHeaders
+</Location>
+
+#######################################
+### Same interpreter registry setup ###
+#######################################
+<IfModule mod_alias.c>
+ Alias /same_interp/registry/ @ServerRoot@/cgi-bin/
+ Alias /same_interp/registry_bb/ @ServerRoot@/cgi-bin/
+ Alias /same_interp/registry_oo_conf/ @ServerRoot@/cgi-bin/
+ Alias /same_interp/perlrun/ @ServerRoot@/cgi-bin/
+</IfModule>
+
+PerlModule Apache::TestHandler
+
+<Location /same_interp/registry_bb>
+ PerlOptions +GlobalRequest
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlFixupHandler Apache::TestHandler::same_interp_fixup
+ PerlResponseHandler ModPerl::RegistryBB
+ PerlOptions +ParseHeaders
+</Location>
+
+<Location /same_interp/registry>
+ # PerlOptions +GlobalRequest
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlFixupHandler Apache::TestHandler::same_interp_fixup
+ PerlResponseHandler ModPerl::Registry
+ PerlOptions +ParseHeaders
+</Location>
+
+<Location /same_interp/registry_oo_conf>
+ PerlOptions +GlobalRequest
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlFixupHandler Apache::TestHandler::same_interp_fixup
+ PerlResponseHandler ModPerl::Registry->handler
+ PerlOptions +ParseHeaders
+</Location>
+
+<Location /same_interp/perlrun>
+ PerlOptions +GlobalRequest
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlFixupHandler Apache::TestHandler::same_interp_fixup
+ PerlResponseHandler ModPerl::PerlRun
+ PerlOptions +ParseHeaders
+</Location>
+
+### the 404 test ###
+<IfModule mod_alias.c>
+ Alias /error_document/ @ServerRoot@/cgi-bin/
+</IfModule>
+
+<Location /error_document>
+ ErrorDocument 404 /error_document/404.pl
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::Registry
+</Location>
+
+### deflate tests ###
+<IfModule mod_alias.c>
+ Alias /registry_bb_deflate/ @ServerRoot@/cgi-bin/
+</IfModule>
+
+#PerlOutputFilterHandler ModPerl::TestFilterDebug::snoop_connection
+PerlModule ModPerl::RegistryBB
+<Location /registry_bb_deflate>
+ PerlOptions +GlobalRequest
+ SetHandler perl-script
+ Options +ExecCGI
+ PerlResponseHandler ModPerl::RegistryBB
+ PerlOptions +ParseHeaders
+ #PerlOutputFilterHandler ModPerl::TestFilterDebug::snoop_request
+ <IfModule mod_deflate.c>
+ SetOutputFilter DEFLATE
+ </IfModule>
+</Location>
+
+# <sandbox-friendly>
+# keep everything self-contained, to avoid problems with sandboxes
+# which break when things try to run off /tmp
+#
+# XXX: consider folding the the following two settings into
+# Apache-Test's autogenerated httpd.conf
+<IfModule mod_cgid.c>
+ ScriptSock logs/cgisock
+</IfModule>
+#
+# XXX: would be nice to have Apache-Test support a new 'tmp' token
+# (similar to t_logs) which will map onto t/tmp by default and provide
+# a new -tmp option to override this default
+<IfModule mod_env.c>
+ SetEnv TMPDIR @t_logs@
+</IfModule>
+# </sandbox-friendly>
+
+
+<IfModule mod_rewrite.c>
+
+ RewriteEngine On
+ <IfVersion < 2.4.0>
+ RewriteLogLevel 9
+ RewriteLog @ServerRoot@/logs/rewrite_log
+ </IfVersion>
+ RewriteRule /rewritetest /rewrite_env/env_val.pl?REWRITE_TEST [E=REWRITE_TEST:GOTCHA,PT,NS,L]
+
+ <Location /rewrite_env>
+ SetHandler perl-script
+ PerlResponseHandler ModPerl::Registry
+ Options +ExecCGI
+ PerlOptions +ParseHeaders
+ </Location>
+</IfModule>
+
+
diff --git a/2_0_13/ModPerl-Registry/t/conf/modperl_extra_startup.pl b/2_0_13/ModPerl-Registry/t/conf/modperl_extra_startup.pl
new file mode 100644
index 0000000..5511694
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/conf/modperl_extra_startup.pl
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use ModPerl::RegistryLoader ();
+
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Process ();
+
+use DirHandle ();
+
+my $proc = Apache2::ServerUtil->server->process;
+my $pool = $proc->pool;
+
+# can't use catfile with server_root as it contains unix dir
+# separators and in a few of our particular tests we compare against
+# win32 separators. in general avoid using server_root_relative in your
+# code, see the manpage for more details
+my $base_dir = Apache2::ServerUtil::server_root_relative($pool, "cgi-bin");
+
+# test the scripts pre-loading by explicitly specifying uri => filename
+my $rl = ModPerl::RegistryLoader->new(package => "ModPerl::Registry");
+my $base_uri = "/cgi-bin";
+for my $file (qw(basic.pl env.pl)) {
+ my $file_path = "$base_dir/$file";
+ my $uri = "$base_uri/$file";
+ $rl->handler($uri, $file_path);
+}
+
+
+# test the scripts pre-loading by using trans sub
+{
+ sub trans {
+ my $uri = shift;
+ $uri =~ s|^/registry_bb/|cgi-bin/|;
+ return Apache2::ServerUtil::server_root_relative($pool, $uri);
+ }
+
+ my $rl = ModPerl::RegistryLoader->new(
+ package => "ModPerl::RegistryBB",
+ trans => \&trans,
+ );
+
+ my @preload = qw(basic.pl env.pl require.pl special_blocks.pl
+ redirect.pl 206.pl content_type.pl);
+
+ for my $file (@preload) {
+ $rl->handler("/registry_bb/$file");
+ }
+}
+
+1;
diff --git a/2_0_13/ModPerl-Registry/t/dirindex.t b/2_0_13/ModPerl-Registry/t/dirindex.t
new file mode 100644
index 0000000..30520a7
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/dirindex.t
@@ -0,0 +1,23 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 2, need [qw(mod_alias.c HTML::HeadParser mod_dir.c)],
+ need_min_module_version CGI => 3.08;
+
+{
+ my $url = "/dirindex/";
+ my $res = GET $url;
+
+ ok t_cmp($res->header('Content-type'),
+ qr{^text/html},
+ "DirectoryIndex + AddHandler - Content-type");
+
+ ok t_cmp(lc($res->content),
+ '<b>done</b>',
+ "DirectoryIndex + AddHandler - body");
+}
diff --git a/2_0_13/ModPerl-Registry/t/fatalstobrowser.t b/2_0_13/ModPerl-Registry/t/fatalstobrowser.t
new file mode 100644
index 0000000..400d259
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/fatalstobrowser.t
@@ -0,0 +1,51 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil qw(
+ t_cmp t_write_perl_script
+ t_client_log_error_is_expected
+ );
+use Apache::TestRequest qw(GET);
+
+use File::Spec::Functions qw(catfile);
+
+plan tests => 4, need need_module(qw(mod_alias)),
+ need_cgi,
+ need_min_module_version CGI => 99.99,
+ skip_reason('fatalsToBrowser known not to work');
+
+my $file = catfile(Apache::Test::vars('serverroot'),
+ qw(cgi-bin fatalstobrowser.pl));
+
+t_write_perl_script($file, <DATA>);
+
+foreach my $base (qw(cgi-bin registry)) {
+
+ my $url = "$base/fatalstobrowser.pl";
+ my $res = GET $url;
+
+ ok t_cmp($res->code,
+ 200,
+ "error intercepted");
+
+ t_client_log_error_is_expected();
+
+ ok t_cmp($res->content,
+ qr/uninitiated_scalar/,
+ "error message captured and returned");
+}
+
+__END__
+use strict;
+use CGI::Carp qw (fatalsToBrowser);
+
+use CGI;
+
+my $cgi = new CGI;
+print $cgi->header;
+
+print "$uninitiated_scalar";
+
+print "Hello World";
diff --git a/2_0_13/ModPerl-Registry/t/flush.t b/2_0_13/ModPerl-Registry/t/flush.t
new file mode 100644
index 0000000..d126ea8
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/flush.t
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET_BODY);
+
+plan tests => 1, need [qw(mod_alias.c deflate HTML::HeadParser)],
+ need_min_module_version("Compress::Zlib", "1.09"),
+ need_min_apache_version("2.0.48");
+# it requires httpd 2.0.48 because of the bug in mod_deflate:
+# http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22259
+
+require Compress::Zlib;
+
+my $url = "/registry_bb_deflate/flush.pl";
+
+my $expected = "yet another boring test string";
+my $received = GET_BODY $url, 'Accept-encoding' => 'gzip';
+my $decompressed = Compress::Zlib::memGunzip($received);
+
+ok t_cmp(
+ $decompressed,
+ $expected,
+ "test flush body"
+ );
+
diff --git a/2_0_13/ModPerl-Registry/t/ithreads.t b/2_0_13/ModPerl-Registry/t/ithreads.t
new file mode 100644
index 0000000..7d91ce9
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/ithreads.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use Config;
+
+use constant HAS_ITHREADS => ($] >= 5.008001 && $Config{useithreads});
+
+plan tests => 1, need 'mod_alias.c',
+ {"perl 5.8.1 or higher w/ithreads enabled is required" => HAS_ITHREADS};
+
+{
+ # the order of prints on the server side is not important here,
+ # what's important is that we get all the printed strings
+ my @expected = sort map("thread $_", 1..4), "parent";
+ my $url = "/registry_modperl_handler/ithreads_io_n_tie.pl";
+ my $received = GET_BODY_ASSERT($url) || '';
+ my @received = sort split /\n/, $received;
+ ok t_cmp \@received, \@expected;
+}
diff --git a/2_0_13/ModPerl-Registry/t/nph.t b/2_0_13/ModPerl-Registry/t/nph.t
new file mode 100644
index 0000000..f9b29e2
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/nph.t
@@ -0,0 +1,52 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 6, need 'mod_alias.c';
+
+my $url = "/nph/nph-foo.pl";
+
+my %expected = (
+ code => '250',
+ body => "non-parsed headers body",
+ headers => {
+ 'content-type' => 'text/text',
+ 'pragma' => 'no-cache',
+ 'cache-control' => 'must-revalidate, no-cache, no-store',
+ 'expires' => '-1',
+ },
+);
+
+my $res = GET $url;
+
+my %received = (
+ code => $res->code,
+ body => $res->content,
+ headers => $res->headers, # LWP lc's the headers
+);
+
+for my $key (keys %expected) {
+ my $expected = $expected{$key};
+ my $received = $received{$key};
+ if ($key eq 'headers') {
+ for my $header (keys %$expected) {
+ ok t_cmp(
+ $received->{$header},
+ $expected->{$header},
+ "test header $header"
+ );
+ }
+ }
+ else {
+ ok t_cmp(
+ $received,
+ $expected,
+ "test key: $key"
+ );
+ }
+}
+
diff --git a/2_0_13/ModPerl-Registry/t/perlrun_extload.t b/2_0_13/ModPerl-Registry/t/perlrun_extload.t
new file mode 100644
index 0000000..e99fd65
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/perlrun_extload.t
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+use TestCommon::SameInterp;
+
+plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)];
+
+my $url = "/same_interp/perlrun/perlrun_extload.pl";
+my $same_interp = Apache::TestRequest::same_interp_tie($url);
+
+for (1..2) {
+ # should not fail on the second request
+ my $res = same_interp_req_body($same_interp, \&GET, $url);
+ same_interp_skip_not_found(
+ !defined($res),
+ $res,
+ "d1nd1234",
+ "PerlRun requiring an external lib with subs",
+ );
+}
+
diff --git a/2_0_13/ModPerl-Registry/t/prefork.t b/2_0_13/ModPerl-Registry/t/prefork.t
new file mode 100644
index 0000000..00376a3
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/prefork.t
@@ -0,0 +1,48 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use Apache::TestConfig ();
+
+use Apache2::Build ();
+
+my $mpm_is_threaded = Apache2::Build->build_config->mpm_is_threaded();
+
+my %modules = (
+ registry => 'ModPerl::Registry',
+ perlrun => 'ModPerl::PerlRun',
+ registry_prefork => 'ModPerl::RegistryPrefork',
+ perlrun_prefork => 'ModPerl::PerlRunPrefork',
+);
+
+my @aliases = sort keys %modules;
+
+plan tests => 1*@aliases, need 'mod_alias.c',
+ { "can't run under threaded MPMs" => !$mpm_is_threaded };
+
+my $script = "prefork.pl";
+
+# very basic compilation/response test
+for my $alias (qw(registry_prefork perlrun_prefork)) {
+ my $url = "/$alias/$script";
+
+ #t_debug "$url";
+ ok t_cmp GET_BODY($url), "ok $script", "$modules{$alias} test";
+}
+
+# the order is important, we also want to check that prefork specific
+# modules didn't affect the cwd of other modules
+
+# the normal handlers should not find the script in the cwd, as they
+# don't chdir to its directory before running the script
+for my $alias (qw(registry perlrun)) {
+ my $url = "/$alias/$script";
+
+ #t_debug "$url";
+ ok t_cmp GET_BODY($url),
+ qr/prefork didn't chdir into the scripts directory/,
+ "$modules{$alias} test";
+}
diff --git a/2_0_13/ModPerl-Registry/t/redirect.t b/2_0_13/ModPerl-Registry/t/redirect.t
new file mode 100644
index 0000000..b4e304e
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/redirect.t
@@ -0,0 +1,61 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET_BODY HEAD);
+
+use Apache::TestUtil qw(t_catfile_apache);
+
+plan tests => 4, need [qw(mod_alias.c HTML::HeadParser)], need_lwp;
+
+# need LWP to handle redirects
+my $base_url = "/registry/redirect.pl";
+
+{
+ my $redirect_path = "/registry/basic.pl";
+ my $url = "$base_url?$redirect_path";
+ my $vars = Apache::Test::config()->{vars};
+ my $script_file = t_catfile_apache $vars->{serverroot}, 'cgi-bin', 'basic.pl';
+
+ ok t_cmp(
+ GET_BODY($url),
+ "ok $script_file",
+ "test redirect: existing target",
+ );
+}
+
+{
+ my $redirect_path = "/registry/does_not_exists.pl";
+ my $url = "$base_url?$redirect_path";
+ t_client_log_error_is_expected();
+ ok t_cmp(
+ HEAD($url)->code,
+ 404,
+ "test redirect: non-existing target",
+ );
+}
+
+{
+ local $Apache::TestRequest::RedirectOK = 0;
+
+ my $base_url = "/registry/redirect-cookie.pl";
+ my $redirect_path = "/registry/basic.pl";
+ my $url = "$base_url?$redirect_path";
+
+ my $response = HEAD $url;
+
+ ok t_cmp(
+ $response->code,
+ 302,
+ "test Registry style redirect: status",
+ );
+
+ ok t_cmp(
+ $response->header('Set-Cookie'),
+ "mod_perl=ubercool; path=/",
+ "test Registry style redirect: cookie",
+ );
+}
+
diff --git a/2_0_13/ModPerl-Registry/t/regex.t b/2_0_13/ModPerl-Registry/t/regex.t
new file mode 100644
index 0000000..4aba470
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/regex.t
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil qw(t_cmp t_catfile_apache);
+use Apache::TestRequest;
+use Apache::TestConfig ();
+
+my %modules = (
+ registry => 'ModPerl::Registry',
+ registry_bb => 'ModPerl::RegistryBB',
+ perlrun => 'ModPerl::PerlRun',
+);
+
+my @aliases = sort keys %modules;
+
+plan tests => @aliases * 1, need 'mod_alias.c';
+
+my $vars = Apache::Test::config()->{vars};
+my $script_file = t_catfile_apache $vars->{serverroot}, 'cgi-bin', 'basic.pl';
+
+# extended regex quoting
+# CVE-2007-1349 (which doesn't affect any of our shipped handlers)
+
+for my $alias (@aliases) {
+ my $url = "/$alias/basic.pl/(";
+
+ ok t_cmp(
+ GET_BODY($url),
+ "ok $script_file",
+ "$modules{$alias} regex in path_info",
+ );
+}
diff --git a/2_0_13/ModPerl-Registry/t/rewrite_env.t b/2_0_13/ModPerl-Registry/t/rewrite_env.t
new file mode 100644
index 0000000..b3e439d
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/rewrite_env.t
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(GET);
+
+plan tests => 1, need [qw(mod_alias.c mod_rewrite.c)];
+
+{
+ my $url = "/rewritetest";
+ my $res = GET $url;
+
+ ok t_cmp($res->content(),
+ "GOTCHA",
+ 'found environment variable from mod_rewrite');
+}
diff --git a/2_0_13/ModPerl-Registry/t/special_blocks.t b/2_0_13/ModPerl-Registry/t/special_blocks.t
new file mode 100644
index 0000000..2868064
--- /dev/null
+++ b/2_0_13/ModPerl-Registry/t/special_blocks.t
@@ -0,0 +1,140 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# test BEGIN/END blocks's behavior
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use TestCommon::SameInterp;
+
+my %modules = (
+ registry => 'ModPerl::Registry',
+ registry_bb => 'ModPerl::RegistryBB',
+ perlrun => 'ModPerl::PerlRun',
+);
+
+my @aliases = sort keys %modules;
+
+plan tests => @aliases * 4, need [qw(mod_alias.c HTML::HeadParser)];
+
+{
+ # PerlRun always run BEGIN/END since it's never cached
+
+ # see also t/perlrun_extload.t which exercises BEGIN/END blocks
+ # from external modules loaded from PerlRun scripts
+
+ my $alias = "perlrun";
+ my $url = "/same_interp/$alias/special_blocks.pl";
+ my $same_interp = Apache::TestRequest::same_interp_tie($url);
+
+ # if one sub-test has failed to run on the same interpreter, skip
+ # the rest in the same group
+ my $skip = 0;
+
+ my $res = same_interp_req_body($same_interp, \&GET, "$url?begin");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "begin ok",
+ "$modules{$alias} is running BEGIN blocks on the first request",
+ );
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?begin");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "begin ok",
+ "$modules{$alias} is running BEGIN blocks on the second request",
+ );
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?end");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "end ok",
+ "$modules{$alias} is running END blocks on the third request",
+ );
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?end");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "end ok",
+ "$modules{$alias} is running END blocks on the fourth request",
+ );
+}
+
+# To properly test BEGIN/END blocks in registry implmentations
+# that do caching, we need to manually reset the registry* cache
+# for each given script, before starting each group of tests.
+
+
+for my $alias (grep !/^perlrun$/, @aliases) {
+ my $url = "/same_interp/$alias/special_blocks.pl";
+ my $same_interp = Apache::TestRequest::same_interp_tie($url);
+
+ # if one sub-test has failed to run on the same interpreter, skip
+ # the rest in the same group
+ my $skip = 0;
+
+ # clear the cache of the registry package for the script in $url
+ my $res = same_interp_req_body($same_interp, \&GET, "$url?uncache");
+ $skip++ unless defined $res;
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?begin");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "begin ok",
+ "$modules{$alias} is running BEGIN blocks on the first request",
+ );
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?begin");
+ $skip++ unless defined $res;
+ t_debug($res);
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "",
+ "$modules{$alias} is not running BEGIN blocks on the second request",
+ );
+
+ $same_interp = Apache::TestRequest::same_interp_tie($url);
+ $skip = 0;
+
+ # clear the cache of the registry package for the script in $url
+ $res = same_interp_req_body($same_interp, \&GET, "$url?uncache");
+ $skip++ unless defined $res;
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?end");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "end ok",
+ "$modules{$alias} is running END blocks on the first request",
+ );
+
+ $res = $skip ? undef : same_interp_req_body($same_interp, \&GET,
+ "$url?end");
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ $res,
+ "end ok",
+ "$modules{$alias} is running END blocks on the second request",
+ );
+}
diff --git a/2_0_13/NOTICE b/2_0_13/NOTICE
new file mode 100644
index 0000000..3f59805
--- /dev/null
+++ b/2_0_13/NOTICE
@@ -0,0 +1,2 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/2_0_13/README b/2_0_13/README
new file mode 100644
index 0000000..a9d3739
--- /dev/null
+++ b/2_0_13/README
@@ -0,0 +1,85 @@
+This is mod_perl version 2.0
+
+*** Prerequisites ***
+
+Apache:
+ Dynamic mod_perl (DSO): Apache 2.0.47 - 2.4.57.
+ Static mod_perl: Apache 2.0.51 - 2.4.57.
+
+ Newer Apache versions may work with this version of mod_perl. If
+ not, the svn version likely will, which can be obtained from:
+ http://perl.apache.org/download/source.html#Development_mod_perl_2_0_Source_Distribution
+
+Perl:
+ Any stable version of Perl currently in support by the Perl community,
+ as described in recent Perl distributions' "perlpolicy.pod" document.
+
+ Newer Perl versions may work with this version of mod_perl. If not,
+ the svn version likely will (see above).
+
+ Many older Perl versions also work with this version of mod_perl:
+ Perls back to version 5.8.2 (and possibly earlier in some build
+ configurations) are currently believed to work, but this is not
+ guaranteed to be the case, either now or in the future.
+
+*** Status ***
+
+mod_perl is currently considered stable.
+
+The following test failures are known (see CPAN RT #118919):
+
+ t/filter/in_bbs_inject_header.t (Fails tests 22, 26 and 30)
+
+There is currently a known test failure on Windows when using Perls built
+with the PERL_IMPLICIT_SYS build option enabled (which it is by default):
+
+ t/modperl/env.t (Fails many tests)
+
+Various other tests are also known to fail in certain configurations on
+Windows, including but not limited to:
+
+ t/modperl/setupenv.t (Fails tests 8, 22, 29, 36, 50 and 57)
+ t/preconnection/note.t (Fails test 1)
+
+*** Documentation ***
+
+Documentation can be found in the docs/ directory. Currently they
+don't get installed on 'make install'. Certain API documentation can
+be found in docs/api/. The online version is at
+http://perl.apache.org/docs/2.0/.
+
+*** Todo ***
+
+mod_perl-2.0 is not 100% feature complete with the 1.xx version.
+See the files in the todo/ directory for what remains to be done. Some
+of those features will be implemented after 2.0 is released. The goal
+is to empty the file todo/release and document/test/verify the API
+that's going to be supported by 2.0. More API will be supported post
+2.0 release.
+
+*** Support ***
+
+For comments, questions, bug-reports, etc., join the mod_perl users
+list by sending mail to modperl-subscribe@perl.apache.org.
+
+Bugs can also be reported at:
+https://rt.cpan.org/Dist/Display.html?Name=mod_perl
+which can be accessed from the "Issues" link in the left-hand menu on
+the metacpan.org page, https://metacpan.org/pod/mod_perl2 .
+(Note: You will need to log in to https://rt.cpan.org in order to get
+the "Report a new bug" button on the bug tracker page.)
+
+When reporting bugs please follow the instructions at:
+http://perl.apache.org/docs/2.0/user/help/help.html#Reporting_Problems
+
+For announcements join the mod_perl announce list by sending mail to
+announce-subscribe@perl.apache.org.
+
+*** Developers ***
+
+Development discussion takes place on dev (at) perl.apache.org
+
+*** Authors ***
+
+mod_perl-2.0 was designed and written by Doug MacEachern, with
+contributions from many others (see Changes files).
diff --git a/2_0_13/README-SVN b/2_0_13/README-SVN
new file mode 100644
index 0000000..ff929f5
--- /dev/null
+++ b/2_0_13/README-SVN
@@ -0,0 +1,59 @@
+this is a very simple document that outlines some of the important
+details about the mod_perl svn repository.
+
+
+LAYOUT
+
+the mod_perl project at the Apache Software Foundation lives here
+
+ http://svn.apache.org/repos/asf/perl/
+
+and uses the following structure
+
+ modperl/trunk # equivalent to cvs HEAD - currently
+ # the mod_perl 2.0 development branch
+
+ modperl/tags # every official mod_perl release
+
+ modperl/docs/trunk # the mod_perl documentation project
+
+modperl/trunk includes the following svn:externals properties:
+
+ % cd modperl
+ % svn propedit svn:externals .
+ [vi pops up]
+Apache-Test https://svn.apache.org/repos/asf/perl/Apache-Test/trunk
+Apache-Reload https://svn.apache.org/repos/asf/perl/Apache-Reload/trunk
+Apache-SizeLimit https://svn.apache.org/repos/asf/perl/Apache-SizeLimit/trunk
+docs https://svn.apache.org/repos/asf/perl/modperl/docs/trunk/src/docs/2.0
+
+DEVELOPER ACCESS
+
+assuming that you have already been granted commit access to the repository,
+you should follow the following steps to checkout mod_perl
+
+Change your password via:
+https://svn.apache.org/change-password
+
+ $ svn checkout https://svn.apache.org/repos/asf/perl/modperl/trunk/ mod_perl-2.0
+
+if you want to test that your commit access is working, this file is
+an acceptable place to take a test drive.
+
+
+FURTHER READING
+
+for more details, see
+
+ http://perl.apache.org/docs/2.0/user/install/install.html
+
+for information on getting httpd and mod_perl from svn, as well as
+
+ http://svnbook.red-bean.com/
+
+for svn information in general.
+
+svn for cvs users (including migration tools):
+
+ http://svnbook.red-bean.com/en/1.0/apa.html
+
diff --git a/2_0_13/RELEASE b/2_0_13/RELEASE
new file mode 100644
index 0000000..41b7404
--- /dev/null
+++ b/2_0_13/RELEASE
@@ -0,0 +1,211 @@
+Instructions for mod_perl 2.0 Release Manager
+
+0. make sure your public key is in the KEYS file in the mod_perl docs.
+ you should only need to do this if this is your first time playing
+ Release Manager
+
+ $ cd mod_perl-docs
+ $ grep $USER src/dist/KEYS
+
+ note that the KEYS file itself contains all the instructions you
+ need on how to add your key. if you need further help on gpg
+ (like how to create a key in the first place) you can look here
+
+ https://people.apache.org/~geoff/gpghowto.html
+
+ Copy the KEYS file into place:
+ % scp KEYS people.apache.org:/www/www.apache.org/dist/perl/KEYS
+
+ If this is your first release, ask someone with APML karma on PAUSE
+ to verify you have the appropriate permissions. Likely someone on
+ the PMC can do this.
+
+ a. login into https://pause.perl.org
+ b. menu click: Select Mailinglist/Action
+ c. choose APML and Change Permissions and click go
+ d. click 3.1 Make somebody else co-maintainer
+ e. choose the modules to give the perms to
+ type the username of the new co-maintainer
+ f. if you happen to know that packages were added this release,
+ make sure you give the correct permissions to them.
+
+1. 'make mydist' - to make sure nothing is missing from the manifest,
+ etc. Now test this generated package mod_perl-2.0.13.tar.gz (not
+ the current build) with as many
+ configurations as possible on as many platforms as possible,
+ unpacking the package each time afresh.
+
+ a. edit ./Changes
+ - change -dev to -rc\d+ starting with -rc1
+ - edit META.yml to the rc\d version above in the version key
+
+ b. commit Changes
+ % svn ci -m "2.0.13 rc1" Changes
+
+ c. nuke any preinstalled mod_perl libs and run 'make test'
+
+ d. test that you can 'make install' and then run 'make test' again
+
+ e. test whether we are still 100% OK on systems with no LWP:
+ % APACHE_TEST_PRETEND_NO_LWP=1 make test
+
+ f. build and test as root. double check that you have started from a
+ fresh source, without having any stale dirs from the previous
+ build laying around.
+
+2. once confident that the package is good, commit the release candidate
+ to https://dist.apache.org/repos/dist/dev/perl and post 24 hour-ish
+ candidate alert to the modperl/dev list (may be longer to give most
+ people a chance to catch up). no need to tag this package
+
+ Subject: [RELEASE CANDIDATE]: mod_perl-2.0.13 RC\d+
+
+2a. if problems are detected during stage 2, repeat stages 1 and 2.
+
+3. when the package has been reported to be good, prepare a new
+ package to be released
+
+ a. edit ./Changes:
+ - remove -rc\d+
+ - add release date
+ - edit META.yml to remove the -rc\d+ from the version key
+
+ b. check ./README and ./Makefile.PL
+ - make sure supported httpd versions (dso & static) are current
+
+ c. rerun:
+ % perl Makefile.PL
+ make sure tag looks right
+ % make -n tag
+
+ d. commit Changes README Makefile.PL
+ % svn ci -m "2.0.13 release" Changes README Makefile.PL
+
+ e. tag
+ % make tag
+
+ f. Update the svn:externals in the new tag to refer to the new docs tag that
+ was created by the previous step:
+ % svn co https://svn.apache.org/repos/asf/perl/modperl/tags/2_0_13
+ % svn propedit svn:externals 2_0_13
+ Update the docs line from:
+ ^/perl/modperl/docs/trunk/src/docs/2.0
+ to:
+ ^/perl/modperl/docs/tags/2_0_13/src/docs/2.0
+ The complete svn:externals should now look like:
+ % svn propget svn:externals 2_0_13
+ Apache-Test ^/perl/Apache-Test/tags/<X>
+ Apache-Reload ^/perl/Apache-Reload/tags/<Y>
+ Apache-SizeLimit ^/perl/Apache-SizeLimit/tags/<Z>
+ docs ^/perl/modperl/docs/tags/2_0_13/src/docs/2.0
+ where <X>, <Y> and <Z> are the tags of the releases of Apache-Test,
+ Apache-Reload and Apache-SizeLimit included in this release of mod_perl.
+ % svn ci -m "2.0.13 release"
+
+ g. create the final package
+ % make dist
+
+ h. test the final package again at least once
+
+4. Tarball signing
+
+ (depending on whether you use GPG or PGP, pick the first or the
+ second set of the commands):
+
+ a. sign your local copy of the tarball:
+
+ % gpg --detach-sign --armor mod_perl-2.0.13.tar.gz
+
+ % pgps -b --armor mod_perl-2.0.13.tar.gz
+
+ b. create SHA256 and SHA512 checksums of the tarball:
+ % sha256sum mod_perl-2.0.13.tar.gz >mod_perl-2.0.13.tar.gz.sha256
+ % sha512sum mod_perl-2.0.13.tar.gz >mod_perl-2.0.13.tar.gz.sha512
+
+5. Release the package and update links
+
+ a. commit the tarball, the signature file and the checksum files to
+ https://dist.apache.org/repos/dist/release/perl - ask the PMC
+ chair to give you the needed permissions if you do not have them.
+
+ b. delete the previous release's files from the same location (they will
+ already have been archived at https://archive.apache.org/dist/perl/)
+
+ c. update the example command-lines in README.html in the same location
+
+ d. ask one of the other developers to double check the signature file
+ and tarball: download both files and verify the signature:
+
+ https://www.apache.org/dist/perl/mod_perl-2.0.13.tar.gz.asc
+ https://www.apache.org/dist/perl/mod_perl-2.0.13.tar.gz
+
+ % gpg --verify mod_perl-2.0.13.tar.gz.asc
+
+ % pgpv mod_perl-2.0.13.tar.gz.asc
+
+ e. respond to the automated email that will arrive requesting that release
+ data be filled in at https://reporter.apache.org/addrelease.html?perl
+
+ f. update the version and release date in the docs:
+ % vi modperl-docs/src/download/index_top.html
+ % vi modperl-docs/doap_Perl.rdf
+ and commit.
+ % svn ci -m "2.0.13 release" \
+ modperl-docs/src/download/index_top.html \
+ modperl-docs/doap_Perl.rdf
+
+ Now run modperl-docs/bin/site_build to generate a local copy of the
+ website, and commit that to https://svn.apache.org/repos/asf/perl/site
+
+ (Alternatively, if running modperl-docs/bin/site_build is too difficult
+ on your local machine, you can just directly edit download/index.html
+ with the changes that were made to modperl-docs/download/index_top.html)
+
+ The change to the website will appear at https://perl.apache.org/ sometime
+ later (but maybe not until the next day).
+
+6. Upload the package to CPAN
+
+7. Announce the package
+
+ a. post to the following lists:
+
+ o dev/perl.apache.org
+ o modperl/perl.apache.org
+ o announce/apache.org
+
+ Note, to post to announce@, you must be sending from an apache.org address.
+
+ Subject: [ANNOUNCE] mod_perl 2.0.13
+
+ include:
+ - link at perl.apache.org:
+ https://perl.apache.org/download/index.html
+ - SHA256 and SHA512 sigs
+ - the latest Changes
+
+8. Prepare for the next cycle
+
+ a. increment version in lib/mod_perl2.pm
+
+ b. increment version in META.yml
+
+ c. edit ./Changes:
+ - start a new item with incremented version + '-dev'
+
+ =item 2.0.14-dev
+
+ d. add a release entry in STATUS
+
+ e. update this file versions to make it easy to copy-n-paste things
+ on the next release:
+ % perl -pi.bak -e 's/(\d+)([._])(\d+)(\2)(\d+)/join($2, $1, $3, $5+1)/eg' RELEASE
+
+ f. commit the changed files
+ % svn ci -m "start 2.0.13-dev cycle" Changes META.yml lib/mod_perl2.pm \
+ STATUS RELEASE
+
+9. Old Versions
+
+ Remind other developers to delete versions older then the prior release
+ from CPAN. Old releases can always be found on BACKPAN.
diff --git a/2_0_13/STATUS b/2_0_13/STATUS
new file mode 100644
index 0000000..1083f10
--- /dev/null
+++ b/2_0_13/STATUS
@@ -0,0 +1,44 @@
+mod_perl 2.0 STATUS: -*-text-*-
+ Last modified at [$Date$]
+
+Release:
+--------
+ 2.000.12 : Released Jan 30, 2022
+ 2.000.11 : Released Oct 05, 2019
+ 2.000.10 : Released Oct 27, 2016
+ 2.000.09 : Released Jun 18, 2015
+ 2.000.08 : Released Apr 17, 2013
+ 2.000.07 : Released Jun 05, 2012
+ 2.000.06 : Released Apr 24, 2012
+ 2.000.05 : Released Feb 07, 2011
+ 2.000.04 : Released Apr 16, 2008
+ 2.000.03 : Released Nov 29, 2006
+ 2.000.02 : Released Oct 20, 2005
+ 2.000.01 : Released Jun 17, 2005
+ 2.000.00 : Released May 20, 2005
+ 1.999.23 : Released May 03, 2005
+ 1.999.22 : Released Apr 14, 2005
+ 1.999.21 : Released Jan 22, 2005
+ 1.999.20 : Released Jan 05, 2005
+ 1.99_19 : Released Dec 22, 2004
+ 1.99_18 : Released Dec 12, 2004
+ 1.99_17 : Released Oct 22, 2004
+ 1.99_16 : Released Aug 22, 2004
+ 1.99_15 : Released Aug 20, 2004
+ 1.99_14 : Released May 21, 2004
+ 1.99_13 : Released Mar 08, 2004
+ 1.99_12 : Released Dec 22, 2003
+ 1.99_11 : Released Nov 10, 2003
+ 1.99_10 : Released Sep 30, 2003
+ 1.99_09 : Released Apr 28, 2003
+ 1.99_08 : Released Jan 10, 2003
+ 1.99_07 : Released Sep 27, 2002
+ 1.99_06 : Not released
+ 1.99_05 : Released Aug 20, 2002
+ 1.99_04 : Released Jun 21, 2002
+ 1.99_03 : Released Jun 16, 2002
+ 1.99_02 : Released Jun 01, 2002
+ 1.99_01 : Released Apr 06, 2002
+
+Issues, bugs and features and their implementation status are spread
+across several files under the todo/ directory
diff --git a/2_0_13/SVN-MOVE b/2_0_13/SVN-MOVE
new file mode 100644
index 0000000..e98bfc1
--- /dev/null
+++ b/2_0_13/SVN-MOVE
@@ -0,0 +1,30 @@
+This file tracks the things that need to be done to accomplish the
+move of modperl projects to SVN:
+
+* missing commit template files (à là CVS)
+ PR:
+ Obtained from:
+ Submitted by:
+ Reviewed by:
+ ...
+
+* commit messages should trim the unrelated crap in the file path
+ e.g. currently we get:
+
+ --- perl/modperl/docs/trunk/src/search/swish.conf (original)
+ +++ perl/modperl/docs/trunk/src/search/swish.conf Fri Nov 19 21:23:25 2004
+and it should be:
+
+ --- src/search/swish.conf (original)
+ +++ src/search/swish.conf Fri Nov 19 21:23:25 2004
+
+so it can be applied/edited easily.
+
+* improve the commit message subject line to print only important info
+ (currently may print 100 files listed in the subject), e.g.:
+
+ Subject: svn commit: r105803 - in httpd/test/trunk/perl-framework: . Apache-Test Apache-Test/lib/Apache Apache-Test/t Apache-Test/t/conf c-modules c-modules/authany c-modules/client_add_filter c-modules/eat_post c-modules/echo_post c-modules/echo_post_chunk c-modules/input_body_filter c-modules/list_modules c-modules/nntp_like c-modules/random_chunk c-modules/test_apr_uri c-modules/test_pass_brigade c-modules/test_rwrite c-modules/test_ssl t t/conf t/conf/ssl t/htdocs/modules/access/htaccess t/htdocs/modules/cgi t/htdocs/modules/rewrite t/modules
+
+ Proposed Subject format:
+
+ $svn_id $first_subdir/$first_file ($trunk)
diff --git a/2_0_13/bin/mp2bug b/2_0_13/bin/mp2bug
new file mode 100755
index 0000000..c3a312a
--- /dev/null
+++ b/2_0_13/bin/mp2bug
@@ -0,0 +1,36 @@
+#!perl
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+use strict;
+use warnings FATAL => 'all';
+
+use FindBin;
+
+use constant IS_MOD_PERL_BUILD => -e "$FindBin::Bin/../lib/mod_perl2.pm";
+
+if (IS_MOD_PERL_BUILD) {
+ unshift @INC, "$FindBin::Bin/../lib";
+}
+else {
+ eval { require mod_perl2 };
+ if ($@) {
+ die "This script requires mod_perl 2.0\n", "$@";
+ }
+}
+
+require ModPerl::TestReport;
+ModPerl::TestReport->new(@ARGV)->run;
diff --git a/2_0_13/build/config.pl b/2_0_13/build/config.pl
new file mode 100644
index 0000000..7b9e09c
--- /dev/null
+++ b/2_0_13/build/config.pl
@@ -0,0 +1,10 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use FindBin qw($Bin);
+use lib "$Bin/../lib";
+
+use ModPerl::Config ();
+
+print ModPerl::Config::as_string();
diff --git a/2_0_13/build/make_etags b/2_0_13/build/make_etags
new file mode 100644
index 0000000..703588a
--- /dev/null
+++ b/2_0_13/build/make_etags
@@ -0,0 +1,27 @@
+search=".. ../.."
+for dir in $search; do
+ if test -d "`pwd`/$dir/modperl-2.0"; then
+ root="`pwd`/$dir"
+ echo "root=$root"
+ fi
+done
+
+#e.g. symlink to $HOME/perl/perl-current
+#XXX: perl has its own (more robust) TAGS generator: emacs/ptags
+perl_src=$root/perl/
+#XXX: apache has its own: build/MakeEtags
+apache_src=$root/httpd-2.0/
+modperl_src=$root/modperl-2.0/src/
+xs_src=$root/modperl-2.0/xs
+
+cd $root/modperl-2.0
+rm -f src/modules/perl/etag_files
+
+for dir in $apache_src $modperl_src $perl_src $xs_src; do
+ echo $dir
+ find $dir -follow -name '*.[ch]' >> src/modules/perl/etag_files
+done
+
+(cd src/modules/perl && etags `cat etag_files`)
+
+rm -f src/modules/perl/etag_files
diff --git a/2_0_13/build/make_rpm_spec b/2_0_13/build/make_rpm_spec
new file mode 100755
index 0000000..2ad2c4e
--- /dev/null
+++ b/2_0_13/build/make_rpm_spec
@@ -0,0 +1,146 @@
+#!perl
+use strict;
+
+require "./lib/mod_perl2.pm";
+
+my $dev_build = is_dev_build();
+my $release = $dev_build ? svn_release() : 1;
+my $version = $mod_perl2::VERSION_TRIPLET;
+my $path = $dev_build ? "mod_perl-$version-$dev_build" : "mod_perl-$version";
+my $tarname = "$path.tar.gz";
+
+my $httpd_ver = min_httpd_ver();
+
+open(my $spec, ">mod_perl.spec") || die "Can't open mod_perl.spec $!";
+
+print $spec <<"EOF";
+%define _version $mod_perl2::VERSION_TRIPLET
+%define _release $release
+%define _source https://apache.org/dist/perl/$tarname
+%define _dirname $path
+%define _httpd_min_ver $httpd_ver
+%define _perl_min_ver 5.6.1
+EOF
+
+print $spec <<'EOF';
+Name: mod_perl
+Version: %{_version}
+Release: %{_release}
+Summary: An embedded Perl interpreter for the Apache Web server
+Group: System Environment/Daemons
+License: Apache License, Version 2.0
+Packager: mod_perl Development Team <dev@perl.apache.org>
+URL: https://perl.apache.org/
+Source: %{_source}
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Requires: httpd >= %{_httpd_min_ver}
+BuildRequires: perl >= %{_perl_min_ver}
+BuildRequires: httpd-devel >= %{_httpd_min_ver}
+BuildRequires: apr-devel, apr-util-devel
+
+%description
+Mod_perl incorporates a Perl interpreter into the Apache web server,
+so that the Apache web server can directly execute Perl code.
+Mod_perl links the Perl runtime library into the Apache web server and
+provides an object-oriented Perl interface for Apache's C language
+API. The end result is a quicker CGI script turnaround process, since
+no external Perl interpreter has to be started.
+
+Install mod_perl if you're installing the Apache web server and you'd
+like for it to directly incorporate a Perl interpreter.
+
+%package devel
+Summary: Files needed for building XS modules that use mod_perl
+Group: Development/Libraries
+Requires: mod_perl = %{version}-%{release}, httpd-devel
+
+%description devel
+The mod_perl-devel package contains the files needed for building XS
+modules that use mod_perl.
+
+%prep
+%setup -q -n %{_dirname}
+
+%build
+CFLAGS="$RPM_OPT_FLAGS" %{__perl} Makefile.PL </dev/null \
+ PREFIX=$RPM_BUILD_ROOT/usr \
+ INSTALLDIRS=vendor \
+ MP_APXS=%{_sbindir}/apxs
+make %{?_smp_mflags} OPTIMIZE="$RPM_OPT_FLAGS"
+
+%install
+rm -rf $RPM_BUILD_ROOT
+install -d -m 755 $RPM_BUILD_ROOT%{_libdir}/httpd/modules
+make install \
+ MODPERL_AP_LIBEXECDIR=$RPM_BUILD_ROOT%{_libdir}/httpd/modules \
+ MODPERL_AP_INCLUDEDIR=$RPM_BUILD_ROOT%{_includedir}/httpd
+
+# Remove the temporary files.
+find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';'
+find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';'
+find $RPM_BUILD_ROOT -type f -name '*.bs' -a -size 0 -exec rm -f {} ';'
+find $RPM_BUILD_ROOT -type d -depth -exec rmdir {} 2>/dev/null ';'
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root,-)
+%doc Changes LICENSE README* STATUS SVN-MOVE docs/
+%{_bindir}/*
+%{_libdir}/httpd/modules/mod_perl.so
+%{perl_vendorarch}/auto/*
+%{perl_vendorarch}/Apache/
+%{perl_vendorarch}/Apache2/
+%{perl_vendorarch}/Bundle/
+%{perl_vendorarch}/APR/
+%{perl_vendorarch}/ModPerl/
+%{perl_vendorarch}/*.pm
+%{_mandir}/man?/*
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/httpd/*
+
+%changelog
+EOF
+
+sub min_httpd_ver {
+ my $min_httpd_ver;
+ open my $mk, 'Makefile.PL';
+ while (<$mk>) {
+ if (/MIN_HTTPD_VERSION_DYNAMIC\s*=>\s*'(.*)'/) {
+ $min_httpd_ver = $1;
+ last;
+ }
+ }
+ close $mk;
+ $min_httpd_ver;
+}
+
+sub svn_release {
+ open my $svn, "<.svn/entries";
+ my $revision;
+ while (<$svn>) {
+ if (/revision="(\d+)"/) {
+ $revision = $1;
+ last;
+ }
+ }
+ close $svn;
+ $revision;
+}
+
+sub is_dev_build {
+ my $dev;
+ open my $fh, 'Changes';
+ while (<$fh>) {
+ if (/^=item.*-(dev|rc\d+)/) {
+ $dev = $1;
+ last;
+ }
+ last if /^=item/;
+ }
+ close $fh;
+ $dev;
+}
diff --git a/2_0_13/build/source_scan.pl b/2_0_13/build/source_scan.pl
new file mode 100644
index 0000000..3a6da0e
--- /dev/null
+++ b/2_0_13/build/source_scan.pl
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+#requires C::Scan 0.75+
+
+use lib qw(lib Apache-Test/lib);
+
+use strict;
+use Apache2::ParseSource ();
+use ModPerl::ParseSource ();
+use ModPerl::FunctionMap ();
+use ModPerl::WrapXS (); #XXX: we should not need to require this here
+
+my $p = Apache2::ParseSource->new(prefixes => ModPerl::FunctionMap->prefixes,
+ @ARGV);
+
+$p->parse;
+
+$p->write_constants_pm;
+
+$p->write_functions_pm;
+
+$p->write_structs_pm;
+
+$p = ModPerl::ParseSource->new(@ARGV);
+
+$p->parse;
+
+$p->write_functions_pm;
diff --git a/2_0_13/build/win32_fetch_apxs b/2_0_13/build/win32_fetch_apxs
new file mode 100755
index 0000000..ee6c964
--- /dev/null
+++ b/2_0_13/build/win32_fetch_apxs
@@ -0,0 +1,101 @@
+#!C:/Perl/bin/perl
+###################################################################
+# apxs, apr-config, and apu-config are Apache utilities used #
+# to both get certain configuration information and also to #
+# assist in building Apache modules. These utilities have not #
+# yet been officially ported to Win32. The following will fetch #
+# and install a development version of these scripts which can #
+# be used in both mod_perl 2 and Apache C modules. #
+# #
+# Please report problems in installing or using these utilties to #
+# Randy Kobes <randy@theoryx5.uwinnipeg.ca> #
+###################################################################
+use strict;
+use warnings;
+use Getopt::Long;
+use File::Spec::Functions;
+use File::Path;
+use ExtUtils::MakeMaker qw(prompt);
+use Cwd;
+
+die "This is intended for Win32" unless ($^O =~ /Win32/i);
+
+my $prefix;
+GetOptions( 'with-apache2=s' => \$prefix);
+unless ($prefix and -d $prefix) {
+ die << 'END';
+
+I could not determine a valid Apache2 directory. Please
+run this script specifying the option
+ --with-apache2=/Path/to/Apache2
+where /Path/to/Apache2 is the location of your installed
+Apache2 top-level directory.
+
+END
+}
+
+exit 0 if (-e catfile($prefix, 'bin', 'apxs.bat'));
+
+print << 'END';
+
+----------------------------------------------------------------------
+I could not find an apxs utility, which will be used in certain parts
+of the build, if present. This utility (and the apr-config and
+apu-config utilities) have not yet been ported to Apache2 on Win32,
+but a development port is available. You can either
+
+- ignore installing apxs by answering "no" at the prompt below
+ (mod_perl will still build),
+- install apxs by answering "yes" at the prompt below,
+- quit now, run the "fetch_win32_apxs.pl" script in the build/ directory
+ to fetch and install the utilities, and then rebuild mod_perl,
+- quit now, and from https://apache.org/dist/perl/win32-bin/ grab
+ apxs_win32.tar.gz; when unpacked, this contains a README explaining
+ how to install the utilities. Afterwards, rebuild mod_perl.
+----------------------------------------------------------------------
+
+END
+
+my $ans = prompt('Install apxs now?', 'yes');
+exit 0 unless $ans =~ /^y/i;
+
+my $prog;
+for my $trial(qw(Apache.exe httpd.exe)) {
+ next unless -e File::Spec->catfile($prefix, 'bin', $trial);
+ $prog = $trial;
+ last;
+}
+die "Could not determine the Apache2 binary name" unless $prog;
+
+require LWP::Simple;
+LWP::Simple->import(qw(is_success getstore));
+
+my $file = 'apxs_win32.tar.gz';
+unless (-e $file) {
+ my $remote = 'https://apache.org/dist/perl/win32-bin/' . $file;
+ print "Fetching $remote ... ";
+ die "Download of $remote failed"
+ unless (is_success(getstore($remote, $file)));
+ print " done!\n";
+}
+
+require Archive::Tar;
+my $cwd = getcwd;
+my $dir = 'apxs';
+my $arc = Archive::Tar->new($file, 1);
+$arc->extract($arc->list_files());
+die "Unpacking $file failed" unless (-d $dir);
+
+print "chdir $dir\n";
+chdir $dir or die "chdir to $dir failed: $!";
+
+my @args = ($^X, 'Configure.pl',
+ "--with-apache2=$prefix",
+ "--with-apache-prog=$prog");
+print "@args\n";
+system(@args) == 0 or die "system @args failed: $?";
+
+chdir $cwd;
+#rmtree($dir, 1, 1) or warn "rmtree of $dir failed: $!";
+#print "unlink $file\n\n";
+#unlink $file or warn "unlink of $file failed: $!";
diff --git a/2_0_13/build/xs_generate.pl b/2_0_13/build/xs_generate.pl
new file mode 100644
index 0000000..74761b5
--- /dev/null
+++ b/2_0_13/build/xs_generate.pl
@@ -0,0 +1,11 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use lib qw(lib Apache-Test/lib);
+
+use Apache::TestConfig (); # needed to resolve circular use dependency
+
+use ModPerl::WrapXS ();
+
+my $xs = ModPerl::WrapXS->new;
+
+$xs->generate;
+
diff --git a/2_0_13/lib/APR/XSLoader.pm b/2_0_13/lib/APR/XSLoader.pm
new file mode 100644
index 0000000..fc390f2
--- /dev/null
+++ b/2_0_13/lib/APR/XSLoader.pm
@@ -0,0 +1,38 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package APR::XSLoader;
+
+use strict;
+use warnings FATAL => 'all';
+
+use XSLoader ();
+
+BEGIN {
+ unless (defined &BOOTSTRAP) {
+ *BOOTSTRAP = sub () { 0 };
+ }
+}
+
+sub load {
+ return unless BOOTSTRAP;
+ # do not change the next line and do not insert anything below it in this
+ # function. XSLoader::load depends on it.
+ goto &XSLoader::load;
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/Apache2/Build.pm b/2_0_13/lib/Apache2/Build.pm
new file mode 100644
index 0000000..19692a8
--- /dev/null
+++ b/2_0_13/lib/Apache2/Build.pm
@@ -0,0 +1,2400 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::Build;
+
+use 5.006;
+use strict;
+use warnings;
+
+use Config;
+use Cwd ();
+use File::Spec::Functions qw(catfile catdir canonpath rel2abs devnull
+ catpath splitpath);
+use File::Basename;
+use ExtUtils::Embed ();
+use File::Copy ();
+
+BEGIN { # check for a sane ExtUtils::Embed
+ unless ($ENV{MP_USE_MY_EXTUTILS_EMBED}) {
+ my ($version, $path)=(ExtUtils::Embed->VERSION,
+ $INC{q{ExtUtils/Embed.pm}});
+ my $msg=<<"EOF";
+I have found ExtUtils::Embed $version at
+
+ $path
+
+This is probably not the right one for this perl version. Please make sure
+there is only one version of this module installed and that it is the one
+that comes with this perl version.
+
+If you insist on using the ExtUtils::Embed as is set the environment
+variable MP_USE_MY_EXTUTILS_EMBED=1 and try again.
+
+EOF
+ if (eval {require Module::CoreList}) {
+ my $req=$Module::CoreList::version{$]}->{q/ExtUtils::Embed/};
+ die "Please repair your Module::CoreList" unless $req;
+ unless ($version eq $req) {
+ $msg.=("Details: expecting ExtUtils::Embed $req ".
+ "(according to Module::CoreList)\n\n");
+ die $msg;
+ }
+ }
+ else {
+ my $req=$Config{privlib}.'/ExtUtils/Embed.pm';
+ unless ($path eq $req) {
+ $msg.="Details: expecting ExtUtils::Embed at $req\n\n";
+ die $msg;
+ }
+ }
+ }
+}
+
+use constant IS_MOD_PERL_BUILD => grep
+ { -e "$_/Makefile.PL" && -e "$_/lib/mod_perl2.pm" } qw(. ..);
+
+use constant AIX => $^O eq 'aix';
+use constant DARWIN => $^O eq 'darwin';
+use constant CYGWIN => $^O eq 'cygwin';
+use constant IRIX => $^O eq 'irix';
+use constant HPUX => $^O eq 'hpux';
+use constant OPENBSD => $^O eq 'openbsd';
+use constant WIN32 => $^O eq 'MSWin32';
+
+use constant MSVC => WIN32() && ($Config{cc} eq 'cl');
+use constant DMAKE => WIN32() && ($Config{make} eq 'dmake');
+
+use constant REQUIRE_ITHREADS => grep { $^O eq $_ } qw(MSWin32);
+use constant PERL_HAS_ITHREADS =>
+ $Config{useithreads} && ($Config{useithreads} eq 'define');
+use constant BUILD_APREXT => WIN32() || CYGWIN();
+
+use ModPerl::Code ();
+use ModPerl::BuildOptions ();
+use Apache::TestTrace;
+use Apache::TestConfig ();
+
+our $VERSION = '0.01';
+our $AUTOLOAD;
+
+sub AUTOLOAD {
+ my $self = shift;
+ my $name = uc ((split '::', $AUTOLOAD)[-1]);
+ unless ($name =~ /^MP_/) {
+ die "no such method: $AUTOLOAD";
+ }
+ unless ($self->{$name}) {
+ return wantarray ? () : undef;
+ }
+ return wantarray ? (split /\s+/, $self->{$name}) : $self->{$name};
+}
+
+#--- apxs stuff ---
+
+our $APXS;
+
+my %apxs_query = (
+ INCLUDEDIR => 'include',
+ LIBEXECDIR => 'modules',
+ CFLAGS => undef,
+ PREFIX => '',
+);
+
+sub ap_prefix_invalid {
+ my $self = shift;
+
+ my $prefix = $self->{MP_AP_PREFIX};
+
+ unless (-d $prefix) {
+ return "$prefix: No such file or directory";
+ }
+
+ my $include_dir = $self->apxs(-q => 'INCLUDEDIR');
+
+ unless (-d $include_dir) {
+ return "include/ directory not found in $prefix";
+ }
+
+ return '';
+}
+
+sub httpd_is_source_tree {
+ my $self = shift;
+
+ return $self->{httpd_is_source_tree}
+ if exists $self->{httpd_is_source_tree};
+
+ my $prefix = $self->dir;
+ $self->{httpd_is_source_tree} =
+ defined $prefix && -d $prefix && -e "$prefix/CHANGES";
+}
+
+# try to find the apxs utility, set $self->{MP_APXS} to the path if found,
+# otherwise to ''
+sub find_apxs_util {
+ my $self = shift;
+
+ if (not defined $self->{MP_APXS}) {
+ $self->{MP_APXS} = ''; # not found
+ }
+
+ my @trys = ($Apache2::Build::APXS,
+ $self->{MP_APXS},
+ $ENV{MP_APXS});
+
+ push @trys, catfile $self->{MP_AP_PREFIX}, 'bin', 'apxs'
+ if exists $self->{MP_AP_PREFIX};
+
+ if (WIN32) {
+ my $ext = '.bat';
+ for (@trys) {
+ $_ .= $ext if ($_ and $_ !~ /$ext$/);
+ }
+ }
+
+ unless (IS_MOD_PERL_BUILD) {
+ #if we are building mod_perl via apxs, apxs should already be known
+ #these extra tries are for things built outside of mod_perl
+ #e.g. libapreq
+ # XXX: this may pick a wrong apxs version!
+ push @trys,
+ Apache::TestConfig::which('apxs'),
+ '/usr/local/apache/bin/apxs';
+ }
+
+ my $apxs_try;
+ for (@trys) {
+ next unless ($apxs_try = $_);
+ chomp $apxs_try;
+ if (-x $apxs_try) {
+ $self->{MP_APXS} = $apxs_try;
+ last;
+ }
+ }
+}
+
+# if MP_AP_DESTDIR was specified this sub will prepend this path to
+# any Apache-specific installation path (that option is used only by
+# package maintainers).
+sub ap_destdir {
+ my $self = shift;
+ my $path = shift || '';
+ return $path unless $self->{MP_AP_DESTDIR};
+
+ if (WIN32) {
+ my ($dest_vol, $dest_dir) = splitpath $self->{MP_AP_DESTDIR}, 1;
+ my $real_dir = (splitpath $path)[1];
+
+ $path = catpath $dest_vol, catdir($dest_dir, $real_dir), '';
+ }
+ else {
+ $path = catdir $self->{MP_AP_DESTDIR}, $path;
+ }
+
+ return canonpath $path;
+}
+
+sub apxs {
+ my $self = shift;
+
+ $self->find_apxs_util() unless defined $self->{MP_APXS};
+
+ my $is_query = (@_ == 2) && ($_[0] eq '-q');
+
+ $self = $self->build_config unless ref $self;
+
+ my $query_key;
+ if ($is_query) {
+ $query_key = 'APXS_' . uc $_[1];
+ if (exists $self->{$query_key}) {
+ return $self->{$query_key};
+ }
+ }
+
+ unless ($self->{MP_APXS}) {
+ my $prefix = $self->{MP_AP_PREFIX} || "";
+ return '' unless -d $prefix and $is_query;
+ my $val = $apxs_query{$_[1]};
+ return defined $val ? ($val ? "$prefix/$val" : $prefix) : "";
+ }
+
+ my $devnull = devnull();
+ my $val = qx($self->{MP_APXS} @_ 2>$devnull);
+ chomp $val if defined $val;
+
+ unless ($val) {
+ # do we have an error or is it just an empty value?
+ my $error = qx($self->{MP_APXS} @_ 2>&1);
+ chomp $error if defined $error;
+ if ($error) {
+ error "'$self->{MP_APXS} @_' failed:";
+ error $error;
+ }
+ else {
+ $val = '';
+ }
+ }
+
+ $self->{$query_key} = $val;
+}
+
+sub apxs_cflags {
+ my $who = caller_package(shift);
+ my $cflags = $who->apxs('-q' => 'CFLAGS');
+ $cflags =~ s/\"/\\\"/g;
+ $cflags;
+}
+
+sub apxs_extra_cflags {
+ my $who = caller_package(shift);
+ my $flags = $who->apxs('-q' => 'EXTRA_CFLAGS');
+ $flags =~ s/\"/\\\"/g;
+ $flags;
+}
+
+sub apxs_extra_cppflags {
+ my $who = caller_package(shift);
+ my $flags = $who->apxs('-q' => 'EXTRA_CPPFLAGS') ." ".
+ $who->apxs('-q' => 'NOTEST_CPPFLAGS');
+ $flags =~ s/\"/\\\"/g;
+ $flags;
+}
+
+sub caller_package {
+ my $arg = shift;
+ return ($arg and ref($arg) eq __PACKAGE__) ? $arg : __PACKAGE__;
+}
+
+my %threaded_mpms = map { $_ => 1 }
+ qw(worker winnt beos mpmt_os2 netware leader perchild threadpool
+ dynamic);
+sub mpm_is_threaded {
+ my $self = shift;
+ my $mpm_name = $self->mpm_name();
+ return exists $threaded_mpms{$mpm_name} ? 1 : 0;
+}
+
+sub mpm_name {
+ my $self = shift;
+
+ return $self->{mpm_name} if $self->{mpm_name};
+
+ if ($self->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/) {
+ delete $threaded_mpms{dynamic} if $self->mp_nonthreaded_ok;
+ return $self->{mpm_name} = 'dynamic' if ($1*1000+$2)*1000+$3>=2003000;
+ }
+
+ # XXX: hopefully apxs will work on win32 one day
+ return $self->{mpm_name} = 'winnt' if WIN32;
+
+ my $mpm_name;
+
+ # httpd >= 2.3
+ if ($self->httpd_version_as_int =~ m/^2[3-9]\d+/) {
+ $mpm_name = 'dynamic';
+ }
+ else {
+ $mpm_name = $self->apxs('-q' => 'MPM_NAME');
+ }
+
+ # building against the httpd source dir
+ unless (($mpm_name and $self->httpd_is_source_tree)) {
+ if ($self->dir) {
+ my $config_vars_file = catfile $self->dir,
+ "build", "config_vars.mk";
+ if (open my $fh, $config_vars_file) {
+ while (<$fh>) {
+ if (/MPM_NAME = (\w+)/) {
+ $mpm_name = $1;
+ last;
+ }
+ }
+ close $fh;
+ }
+ }
+ }
+
+ unless ($mpm_name) {
+ my $msg = 'Failed to obtain the MPM name.';
+ $msg .= " Please specify MP_APXS=/full/path/to/apxs to solve " .
+ "this problem." unless exists $self->{MP_APXS};
+ error $msg;
+ die "\n";
+ }
+
+ return $self->{mpm_name} = $mpm_name;
+}
+
+sub should_build_apache {
+ my ($self) = @_;
+ return $self->{MP_USE_STATIC} ? 1 : 0;
+}
+
+sub configure_apache {
+ my ($self) = @_;
+
+ unless ($self->{MP_AP_CONFIGURE}) {
+ error "You specified MP_USE_STATIC but did not specify the " .
+ "arguments to httpd's ./configure with MP_AP_CONFIGURE";
+ exit 1;
+ }
+
+ unless ($self->{MP_AP_PREFIX}) {
+ error "You specified MP_USE_STATIC but did not speficy the " .
+ "location of httpd's source tree with MP_AP_PREFIX";
+ exit 1;
+ }
+
+ debug "Configuring httpd in $self->{MP_AP_PREFIX}";
+
+ my $httpd = File::Spec->catfile($self->{MP_AP_PREFIX}, 'httpd');
+ $self->{'httpd'} ||= $httpd;
+ push @Apache::TestMM::Argv, ('httpd' => $self->{'httpd'});
+
+ my $mplibpath = '';
+ my $ldopts = $self->ldopts;
+
+ if (CYGWIN) {
+ # Cygwin's httpd port links its modules into httpd2core.dll,
+ # instead of httpd.exe. In this case, we have a problem,
+ # because libtool doesn't want to include static libs (.a)
+ # into a dynamic lib (.dll). Workaround this by setting
+ # mod_perl.a as a linker argument (including all other flags
+ # and libs).
+ my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}";
+
+ $ldopts = join ' ',
+ '--export-all-symbols',
+ '--enable-auto-image-base',
+ "$self->{cwd}/src/modules/perl/$mplib",
+ $ldopts;
+
+ $ldopts =~ s/(\S+)/-Wl,$1/g;
+
+ } else {
+ my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}";
+ $mplibpath = catfile($self->{cwd}, qw(src modules perl), $mplib);
+ }
+
+ local $ENV{BUILTIN_LIBS} = $mplibpath;
+ local $ENV{AP_LIBS} = $ldopts;
+ local $ENV{MODLIST} = 'perl';
+
+ # XXX: -Wall and/or -Werror at httpd configure time breaks things
+ local $ENV{CFLAGS} = join ' ', grep { ! /\-Wall|\-Werror/ }
+ split /\s+/, $ENV{CFLAGS} || '';
+
+ my $cd = qq(cd $self->{MP_AP_PREFIX});
+
+ # We need to clean the httpd tree before configuring it
+ if (-f File::Spec->catfile($self->{MP_AP_PREFIX}, 'Makefile')) {
+ my $cmd = qq(make clean);
+ debug "Running $cmd";
+ system("$cd && $cmd") == 0 or die "httpd: $cmd failed";
+ }
+
+ my $cmd = qq(./configure $self->{MP_AP_CONFIGURE});
+ debug "Running $cmd";
+ system("$cd && $cmd") == 0 or die "httpd: $cmd failed";
+
+ # Got to build in srclib/* early to have generated files present.
+ my $srclib = File::Spec->catfile($self->{MP_AP_PREFIX}, 'srclib');
+ $cd = qq(cd $srclib);
+ $cmd = qq(make);
+ debug "Building srclib in $srclib";
+ system("$cd && $cmd") == 0 or die "srclib: $cmd failed";
+}
+
+#--- Perl Config stuff ---
+
+my %gtop_config = ();
+sub find_gtop {
+ my $self = shift;
+
+ return %gtop_config if %gtop_config;
+
+ if (%gtop_config = find_gtop_config()) {
+ return %gtop_config;
+ }
+
+ if ($self->find_dlfile('gtop')) {
+ $gtop_config{ldopts} = $self->gtop_ldopts_old();
+ $gtop_config{ccopts} = '';
+ return %gtop_config;
+ }
+
+ return ();
+}
+
+sub find_gtop_config {
+ my %c = ();
+
+ my $ver_2_5_plus = 0;
+ if (system('pkg-config --exists libgtop-2.0') == 0) {
+ # 2.x
+ chomp($c{ccopts} = qx|pkg-config --cflags libgtop-2.0|);
+ chomp($c{ldopts} = qx|pkg-config --libs libgtop-2.0|);
+
+ # 2.0.0 bugfix
+ chomp(my $libdir = qx|pkg-config --variable=libdir libgtop-2.0|);
+ $c{ldopts} =~ s|\$\(libdir\)|$libdir|;
+
+ chomp($c{ver} = qx|pkg-config --modversion libgtop-2.0|);
+ ($c{ver_maj}, $c{ver_min}) = split /\./, $c{ver};
+ $ver_2_5_plus++ if $c{ver_maj} == 2 && $c{ver_min} >= 5;
+
+ if ($ver_2_5_plus) {
+ # some headers were removed in libgtop 2.5.0 so we need to
+ # be able to exclude them at compile time
+ $c{ccopts} .= ' -DGTOP_2_5_PLUS';
+ }
+
+ }
+ elsif (system('gnome-config --libs libgtop') == 0) {
+ chomp($c{ccopts} = qx|gnome-config --cflags libgtop|);
+ chomp($c{ldopts} = qx|gnome-config --libs libgtop|);
+
+ # buggy ( < 1.0.9?) versions fixup
+ $c{ccopts} =~ s|^/|-I/|;
+ $c{ldopts} =~ s|^/|-L/|;
+ }
+
+ # starting from 2.5.0 'pkg-config --cflags libgtop-2.0' already
+ # gives us all the cflags that are needed
+ if ($c{ccopts} && !$ver_2_5_plus) {
+ chomp(my $ginc = `glib-config --cflags`);
+ $c{ccopts} .= " $ginc";
+ }
+
+ if (%c) {
+ $c{ccopts} = " $c{ccopts}";
+ $c{ldopts} = " $c{ldopts}";
+ }
+
+ return %c;
+}
+
+my @Xlib = qw(/usr/X11/lib /usr/X11R6/lib);
+
+sub gtop_ldopts_old {
+ my $self = shift;
+ my $xlibs = "";
+
+ my ($path) = $self->find_dlfile('Xau', @Xlib);
+ if ($path) {
+ $xlibs = "-L$path -lXau";
+ }
+
+ if ($self->find_dlfile('intl')) {
+ $xlibs .= ' -lintl';
+ }
+
+ return " -lgtop -lgtop_sysdeps -lgtop_common $xlibs";
+}
+
+sub gtop_ldopts {
+ exists $gtop_config{ldopts} ? $gtop_config{ldopts} : '';
+}
+
+sub gtop_ccopts {
+ exists $gtop_config{ccopts} ? $gtop_config{ccopts} : '';
+}
+
+sub ldopts {
+ my ($self) = @_;
+
+ my $config = tied %Config;
+ my $ldflags = $config->{ldflags};
+
+ if (WIN32) {
+ $config->{ldflags} = ''; #same as lddlflags
+ }
+ elsif (DARWIN) {
+ #not sure how this can happen, but it shouldn't
+ my @bogus_flags = ('flat_namespace', 'bundle', 'undefined suppress');
+ for my $flag (@bogus_flags) {
+ $config->{ldflags} =~ s/-$flag\s*//;
+ }
+ }
+
+ my $ldopts = ExtUtils::Embed::ldopts();
+ chomp $ldopts;
+
+ my $ld = $self->perl_config('ld');
+
+ if (HPUX && $ld eq 'ld') {
+ while ($ldopts =~ s/-Wl,(\S+)/$1/) {
+ my $cp = $1;
+ (my $repl = $cp) =~ s/,/ /g;
+ $ldopts =~ s/\Q$cp/$repl/;
+ }
+ }
+
+ if ($self->{MP_USE_GTOP}) {
+ $ldopts .= $self->gtop_ldopts;
+ }
+
+ $config->{ldflags} = $ldflags; #reset
+
+ # on Irix mod_perl.so needs to see the libperl.so symbols, which
+ # requires the -exports option immediately before -lperl.
+ if (IRIX) {
+ ($ldopts =~ s/-lperl\b/-exports -lperl/)
+ or warn "Failed to fix Irix symbol exporting\n";
+ }
+
+ $ldopts;
+}
+
+my $Wall =
+ "-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations";
+
+# perl v5.6.1 and earlier produces lots of warnings, so we can't use
+# -Werror with those versions.
+$Wall .= " -Werror" if $] >= 5.006002;
+
+sub ap_ccopts {
+ my ($self) = @_;
+ my $ccopts = "-DMOD_PERL";
+
+ if ($self->{MP_USE_GTOP}) {
+ $ccopts .= " -DMP_USE_GTOP";
+ $ccopts .= $self->gtop_ccopts;
+ }
+
+ if ($self->{MP_MAINTAINER}) {
+ $self->{MP_DEBUG} = 1;
+ if ($self->perl_config('gccversion')) {
+ #same as --with-maintainter-mode
+ $ccopts .= " $Wall";
+ }
+
+ if (!OPENBSD &&
+ $self->has_gcc_version('3.3.2') &&
+ $ccopts !~ /declaration-after-statement/) {
+ debug "Adding -Wdeclaration-after-statement to ccopts";
+ $ccopts .= " -Wdeclaration-after-statement";
+ }
+ }
+
+ if ($self->{MP_COMPAT_1X}) {
+ $ccopts .= " -DMP_COMPAT_1X";
+ }
+
+ if ($self->{MP_DEBUG}) {
+ $self->{MP_TRACE} = 1;
+ my $win32_flags = MSVC ? '-Od -MD -Zi' : '';
+ my $debug_flags = WIN32 ? $win32_flags : '-g';
+ $ccopts .= " $debug_flags" unless $Config{optimize} =~ /$debug_flags/;
+ $ccopts .= ' -DMP_DEBUG';
+ }
+
+ if ($self->{MP_CCOPTS}) {
+ $ccopts .= " $self->{MP_CCOPTS}";
+ }
+
+ if ($self->{MP_TRACE}) {
+ $ccopts .= " -DMP_TRACE";
+ }
+
+ if ($self->has_gcc_version('5.0.0') && $ccopts !~ /-fgnu89-inline/) {
+ $ccopts .= " -fgnu89-inline";
+ }
+
+ if ($self->has_clang && $ccopts !~ /-std=gnu89/) {
+ $ccopts .= " -std=gnu89";
+ }
+
+ # make sure apr.h can be safely included
+ # for example Perl's included -D_GNU_SOURCE implies
+ # -D_LARGEFILE64_SOURCE on linux, but this won't happen on
+ # Solaris, so we need apr flags living in apxs' EXTRA_CPPFLAGS
+ my $extra_cppflags = $self->apxs_extra_cppflags;
+ $ccopts .= " " . $extra_cppflags;
+
+ # Make sure the evil AP_DEBUG is not defined when building mod_perl
+ $ccopts =~ s/ ?-DAP_DEBUG\b//;
+
+ $ccopts;
+}
+
+sub has_gcc_version {
+ my $self = shift;
+ my $requested_version = shift;
+
+ my $has_version = $self->perl_config('gccversion');
+
+ return 0 unless $has_version;
+
+ #Only interested in leading version digits
+ $has_version =~ s/^([0-9.]+).*/$1/;
+
+ my @tuples = split /\./, $has_version, 3;
+ my @r_tuples = split /\./, $requested_version, 3;
+
+ return cmp_tuples(\@tuples, \@r_tuples) == 1;
+}
+
+sub has_clang {
+ my $self = shift;
+
+ my $has_version = $self->perl_config('gccversion');
+
+ return 0 unless $has_version;
+
+ return $has_version =~ m/Clang/;
+}
+
+sub cmp_tuples {
+ my ($num_a, $num_b) = @_;
+
+ while (@$num_a && @$num_b) {
+ my $cmp = shift @$num_a <=> shift @$num_b;
+ return $cmp if $cmp;
+ }
+
+ return @$num_a <=> @$num_b;
+}
+
+sub perl_ccopts {
+ my $self = shift;
+
+ my $cflags = $self->strip_lfs(" $Config{ccflags} ");
+
+ my $fixup = \&{"ccopts_$^O"};
+ if (defined &$fixup) {
+ $fixup->(\$cflags);
+ }
+
+ if (WIN32 and $self->{MP_DEBUG}) {
+ #only win32 has -DDEBUGGING in both optimize and ccflags
+ my $optim = $Config{optimize};
+
+ unless ($optim =~ /-DDEBUGGING/) {
+ $cflags =~ s/$optim//;
+ }
+ }
+
+ if (CYGWIN) {
+ $cflags .= " -DCYGWIN ";
+ }
+
+ $cflags;
+}
+
+sub ccopts_hpux {
+ my $cflags = shift;
+ return if $Config{cc} eq 'gcc'; #XXX?
+ return if $$cflags =~ /(-Ae|\+e)/;
+ $$cflags .= " -Ae ";
+}
+
+# XXX: there could be more, but this is just for cosmetics
+my %cflags_dups = map { $_ => 1 } qw(-D_GNU_SOURCE -D_REENTRANT);
+sub ccopts {
+ my ($self) = @_;
+
+ my $cflags = $self->perl_ccopts . ExtUtils::Embed::perl_inc() .
+ $self->ap_ccopts;
+
+ # remove duplicates of certain cflags coming from perl and ap/apr
+ my @cflags = ();
+ my %dups = ();
+ for (split /\s+/, $cflags) {
+ if ($cflags_dups{$_}) {
+ next if $dups{$_};
+ $dups{$_}++;
+ }
+ push @cflags, $_;
+ }
+ $cflags = "@cflags";
+
+ $cflags;
+}
+
+sub ldopts_prefix {
+ my $self = shift;
+ $self->perl_config('ld') eq 'ld' ? '' : "-Wl,";
+}
+
+sub perl_config_optimize {
+ my ($self, $val) = @_;
+
+ $val ||= $Config{optimize};
+
+ if ($self->{MP_DEBUG}) {
+ return ' ' unless $Config{ccflags} =~ /-DDEBUGGING/;
+ }
+
+ $val;
+}
+
+sub perl_config_ld {
+ my ($self, $val) = @_;
+
+ $val ||= $Config{ld};
+
+ basename $val; #bleedperl hpux value is /usr/bin/ld !
+}
+
+sub perl_config_lddlflags {
+ my ($self, $val) = @_;
+
+ if ($self->{MP_DEBUG}) {
+ if (MSVC) {
+ unless ($val =~ s/-release/-debug/) {
+ $val .= ' -debug';
+ }
+ }
+ }
+
+ if (AIX) {
+ my $Wl = $self->ldopts_prefix;
+
+ # it's useless to import symbols from libperl.so this way,
+ # because perl.exp is incomplete. a better way is to link
+ # against -lperl which has all the symbols
+ $val =~ s|${Wl}-bI:\$\(PERL_INC\)/perl\.exp||;
+ # also in the case of Makefile.modperl PERL_INC is defined
+
+ # this works with at least ld(1) on powerpc-ibm-aix5.1.0.0:
+ # -berok ignores symbols resolution problems (they will be
+ # resolved at run-time
+ # -brtl prepares the object for run-time loading
+ # LDFLAGS already inserts -brtl
+ $val .= " ${Wl}-berok";
+ # XXX: instead of -berok, could make sure that we have:
+ # -Lpath/to/CORE -lperl
+ # -bI:$path/apr.exp -bI:$path/aprutil.exp -bI:$path/httpd.exp
+ # -bI:$path/modperl_*.exp
+ # - don't import modperl_*.exp in Makefile.modperl which
+ # exports -bE:$path/modperl_*.exp
+ # - can't rely on -bI:$path/perl.exp, because it's incomplete,
+ # use -lperl instead
+ # - the issue with using apr/aprutil/httpd.exp is to pick the
+ # right path if httpd wasn't yet installed
+ }
+
+ $val;
+}
+
+sub perl_config {
+ my ($self, $key) = @_;
+
+ my $val = $Config{$key} || '';
+
+ my $method = \&{"perl_config_$key"};
+ if (defined &$method) {
+ return $method->($self, $val);
+ }
+
+ return $val;
+}
+
+sub find_in_inc {
+ my $name = shift;
+ for (@INC) {
+ my $file;
+ if (-e ($file = "$_/auto/Apache2/$name")) {
+ return $file;
+ }
+ }
+}
+
+sub libpth {
+ my $self = shift;
+ $self->{libpth} ||= [split /\s+/, $Config{libpth}];
+ return wantarray ? @{ $self->{libpth} } : $self->{libpth};
+}
+
+sub find_dlfile {
+ my ($self, $name) = (shift, shift);
+
+ require DynaLoader;
+ require AutoLoader; #eek
+
+ my $found = 0;
+ my $loc = "";
+ my (@path) = ($self->libpth, @_);
+
+ for (@path) {
+ if ($found = DynaLoader::dl_findfile($_, "-l$name")) {
+ $loc = $_;
+ last;
+ }
+ }
+
+ return wantarray ? ($loc, $found) : $found;
+}
+
+sub find_dlfile_maybe {
+ my ($self, $name) = @_;
+
+ my $path = $self->libpth;
+
+ my @maybe;
+ my $lib = 'lib' . $name;
+
+ for (@$path) {
+ push @maybe, grep { ! -l $_ } <$_/$lib.*>;
+ }
+
+ return \@maybe;
+}
+
+sub lib_check {
+ my ($self, $name) = @_;
+ return unless $self->perl_config('libs') =~ /$name/;
+
+ return if $self->find_dlfile($name);
+
+ my $maybe = $self->find_dlfile_maybe($name);
+ my $suggest = @$maybe ?
+ "You could just symlink it to $maybe->[0]" :
+ 'You might need to install Perl from source';
+ $self->phat_warn(<<EOF);
+Your Perl is configured to link against lib$name,
+ but lib$name.so was not found.
+ $suggest
+EOF
+}
+
+#--- user interaction ---
+
+sub prompt {
+ my ($self, $q, $default) = @_;
+ return $default if $self->{MP_PROMPT_DEFAULT};
+ require ExtUtils::MakeMaker;
+ ExtUtils::MakeMaker::prompt($q, $default);
+}
+
+sub prompt_y {
+ my ($self, $q) = @_;
+ $self->prompt($q, 'y') =~ /^y/i;
+}
+
+sub prompt_n {
+ my ($self, $q) = @_;
+ $self->prompt($q, 'n') =~ /^n/i;
+}
+
+sub phat_warn {
+ my ($self, $msg, $abort) = @_;
+ my $level = $abort ? 'ERROR' : 'WARNING';
+ warn <<EOF;
+************* $level *************
+
+ $msg
+
+************* $level *************
+EOF
+ if ($abort) {
+ exit 1;
+ }
+ else {
+ sleep 5;
+ }
+}
+
+#--- constructors ---
+
+my $bpm = 'Apache2/BuildConfig.pm';
+
+sub build_config {
+ my $self = shift;
+ my $bpm_mtime = 0;
+
+ $bpm_mtime = (stat _)[9] if $INC{$bpm} && -e $INC{$bpm};
+
+ if (-e "lib/$bpm" and (stat _)[9] > $bpm_mtime) {
+ #reload if Makefile.PL has regenerated
+ unshift @INC, 'lib';
+ delete $INC{$bpm};
+ eval { require Apache2::BuildConfig; };
+ shift @INC;
+ }
+ else {
+ eval { require Apache2::BuildConfig; };
+ }
+
+ return bless {}, (ref($self) || $self) if $@;
+ return Apache2::BuildConfig->new;
+}
+
+sub new {
+ my $class = shift;
+
+ my $self = bless {
+ cwd => Cwd::fastcwd(),
+ MP_LIBNAME => 'mod_perl',
+ MP_APXS => undef, # so we know we haven't tried to set it yet
+ @_,
+ }, $class;
+
+ $self->{MP_APR_LIB} = 'aprext';
+
+ ModPerl::BuildOptions->init($self) if delete $self->{init};
+
+ $self;
+}
+
+sub DESTROY {}
+
+my %default_files = (
+ 'build_config' => 'lib/Apache2/BuildConfig.pm',
+ 'ldopts' => 'src/modules/perl/ldopts',
+ 'makefile' => 'src/modules/perl/Makefile',
+);
+
+sub clean_files {
+ my $self = shift;
+ [sort map { $self->default_file($_) } keys %default_files];
+}
+
+sub default_file {
+ my ($self, $name, $override) = @_;
+ my $key = join '_', 'file', $name;
+ $self->{$key} ||= ($override || $default_files{$name});
+}
+
+sub file_path {
+ my $self = shift;
+
+ # work around when Apache2::BuildConfig has not been created yet
+ return unless $self && $self->{cwd};
+
+ my @files = map { m:^/: ? $_ : join('/', $self->{cwd}, $_) } @_;
+ return wantarray ? @files : $files[0];
+}
+
+sub freeze {
+ require Data::Dumper;
+ local $Data::Dumper::Terse = 1;
+ local $Data::Dumper::Sortkeys = 1;
+ my $data = Data::Dumper::Dumper(shift);
+ chomp $data;
+ $data;
+}
+
+sub save_ldopts {
+ my ($self, $file) = @_;
+
+ $file ||= $self->default_file('ldopts', $file);
+ my $ldopts = $self->ldopts;
+
+ open my $fh, '>', $file or die "open $file: $!";
+ print $fh "#!/bin/sh\n\necho $ldopts\n";
+ close $fh;
+ chmod 0755, $file;
+}
+
+sub noedit_warning_hash {
+ ModPerl::Code::noedit_warning_hash(__PACKAGE__);
+}
+
+sub save {
+ my ($self, $file) = @_;
+
+ delete $INC{$bpm};
+
+ $file ||= $self->default_file('build_config');
+ $file = $self->file_path($file);
+
+ my $obj = $self->freeze;
+ $obj =~ s/^\s{9}//mg;
+ $obj =~ s/^/ /;
+
+ open my $fh, '>', $file or die "open $file: $!";
+
+ #work around autosplit braindeadness
+ my $package = 'package Apache2::BuildConfig';
+
+ print $fh noedit_warning_hash();
+
+ print $fh <<EOF;
+$package;
+
+use Apache2::Build ();
+
+sub new {
+$obj;
+}
+
+1;
+EOF
+
+ close $fh or die "failed to write $file: $!";
+}
+
+sub rebuild {
+ my $self = __PACKAGE__->build_config;
+ my @opts = map { qq[$_='$self->{$_}'] } sort grep /^MP_/, keys %$self;
+ my $command = "perl Makefile.PL @opts";
+ print "Running: $command\n";
+ system $command;
+}
+# % perl -MApache2::Build -e rebuild
+*main::rebuild = \&rebuild if $0 eq '-e';
+
+#--- attribute access ---
+
+sub is_dynamic { shift->{MP_USE_DSO} }
+
+sub default_dir {
+ my $build = shift->build_config;
+
+ return $build->dir || '../apache_x.x/src';
+}
+
+sub dir {
+ my ($self, $dir) = @_;
+
+ if ($dir) {
+ for (qw(ap_includedir)) {
+ delete $self->{$_};
+ }
+ if ($dir =~ m:^\.\.[/\\]:) {
+ $dir = "$self->{cwd}/$dir";
+ }
+ $self->{dir} = $dir;
+ }
+
+ return $self->{dir} if $self->{dir};
+
+ # be careful with the guesswork, or may pick up some wrong headers
+ if (IS_MOD_PERL_BUILD && $self->{MP_AP_PREFIX}) {
+ my $build = $self->build_config;
+
+ if (my $bdir = $build->{'dir'}) {
+ for ($bdir, "../$bdir", "../../$bdir") {
+ if (-d $_) {
+ $dir = $_;
+ last;
+ }
+ }
+ }
+ }
+
+ $dir ||= $self->{MP_AP_PREFIX};
+
+# we no longer install Apache headers, so don't bother looking in @INC
+# might end up finding 1.x headers anyhow
+# unless ($dir and -d $dir) {
+# for (@INC) {
+# last if -d ($dir = "$_/auto/Apache2/include");
+# }
+# }
+ return $self->{dir} = $dir ? canonpath(rel2abs $dir) : undef;
+}
+
+#--- finding apache *.h files ---
+
+sub find {
+ my $self = shift;
+ my %seen = ();
+ my @dirs = ();
+
+ for my $src_dir ($self->dir,
+ $self->default_dir,
+ '../httpd-2.0')
+ {
+ next unless $src_dir;
+ next unless (-d $src_dir || -l $src_dir);
+ next if $seen{$src_dir}++;
+ push @dirs, $src_dir;
+ #$modified{$src_dir} = (stat($src_dir))[9];
+ }
+
+ return @dirs;
+}
+
+sub ap_includedir {
+ my ($self, $d) = @_;
+
+ return $self->{ap_includedir}
+ if $self->{ap_includedir} and -d $self->{ap_includedir};
+
+ return unless $d ||= $self->apxs('-q' => 'INCLUDEDIR') || $self->dir;
+
+ if (-e "$d/include/ap_release.h") {
+ return $self->{ap_includedir} = "$d/include";
+ }
+
+ $self->{ap_includedir} = $d;
+}
+
+# This is necessary for static builds that needs to make a
+# difference between where the apache headers are (to build
+# against) and where they will be installed (to install our
+# own headers alongside)
+#
+# ap_exp_includedir is where apache is going to install its
+# headers to
+sub ap_exp_includedir {
+ my ($self) = @_;
+
+ return $self->{ap_exp_includedir} if $self->{ap_exp_includedir};
+
+ my $build_vars = File::Spec->catfile($self->{MP_AP_PREFIX},
+ qw(build config_vars.mk));
+ open my $vars, "<$build_vars" or die "Couldn't open $build_vars $!";
+ my $ap_exp_includedir;
+ while (<$vars>) {
+ if (/exp_includedir\s*=\s*(.*)/) {
+ $ap_exp_includedir = $1;
+ last;
+ }
+ }
+
+ $self->{ap_exp_includedir} = $ap_exp_includedir;
+}
+
+sub install_headers_dir {
+ my ($self) = @_;
+ if ($self->should_build_apache) {
+ return $self->ap_exp_includedir();
+ }
+ else {
+ return $self->ap_includedir();
+ }
+}
+
+
+# where apr-config and apu-config reside
+sub apr_bindir {
+ my ($self) = @_;
+
+ $self->apr_config_path unless $self->{apr_bindir};
+ $self->{apr_bindir};
+}
+
+sub apr_generation {
+ my ($self) = @_;
+ return $self->httpd_version_as_int =~ m/2[1-9]\d+/ ? 1 : 0;
+}
+
+# returns an array of apr/apu linking flags (--link-ld --libs) if found
+# an empty array otherwise
+my @apru_link_flags = ();
+sub apru_link_flags {
+ my ($self) = @_;
+
+ return @apru_link_flags if @apru_link_flags;
+
+ # first use apu_config_path and then apr_config_path in order to
+ # resolve the symbols right during linking
+ for ($self->apu_config_path, $self->apr_config_path) {
+ my $flags = '--link-ld --libs';
+ $flags .= ' --ldflags' unless (WIN32);
+ if (my $link = $_ && -x $_ && qx{$_ $flags}) {
+ chomp $link;
+
+ # Change '/path/to/libanything.la' to '-L/path/to -lanything'
+ if (CYGWIN) {
+ $link =~ s|(\S*)/lib([^.\s]+)\.\S+|-L$1 -l$2|g;
+ }
+
+ if ($self->httpd_is_source_tree) {
+ my @libs;
+ while ($link =~ m/-L(\S+)/g) {
+ my $dir = File::Spec->catfile($1, '.libs');
+ push @libs, $dir if -d $dir;
+ }
+ push @apru_link_flags, join ' ', map { "-L$_" } @libs;
+ }
+ push @apru_link_flags, $link;
+ }
+ }
+
+ return @apru_link_flags;
+}
+
+sub apr_config_path {
+ shift->apru_config_path("apr");
+}
+
+sub apu_config_path {
+ shift->apru_config_path("apu");
+}
+
+sub apru_config_path {
+ my ($self, $what) = @_;
+
+ my $key = "${what}_config_path"; # apr_config_path
+ my $mp_key = "MP_" . uc($what) . "_CONFIG"; # MP_APR_CONFIG
+ my $bindir = uc($what) . "_BINDIR"; # APR_BINDIR
+
+ return $self->{$key} if $self->{$key} and -x $self->{$key};
+
+ if (exists $self->{$mp_key} and -x $self->{$mp_key}) {
+ $self->{$key} = $self->{$mp_key};
+ }
+
+ my $config = $self->apr_generation ? "$what-1-config" : "$what-config";
+
+ if (!$self->{$key}) {
+ my @tries = ();
+ if ($self->httpd_is_source_tree) {
+ for my $base (grep defined $_, $self->dir) {
+ push @tries, grep -d $_,
+ map catdir($base, "srclib", $_), qw(apr apr-util);
+ }
+
+ # Check for MP_AP_CONFIGURE="--with-apr[-util]=DIR|FILE"
+ my $what_long = ($what eq 'apu') ? 'apr-util' : 'apr';
+ if ($self->{MP_AP_CONFIGURE} &&
+ $self->{MP_AP_CONFIGURE} =~ /--with-${what_long}=(\S+)/) {
+ my $dir = $1;
+ $dir = dirname $dir if -f $dir;
+ push @tries, grep -d $_, $dir, catdir $dir, 'bin';
+ }
+ }
+ else {
+ push @tries, grep length,
+ map $self->apxs(-q => $_), $bindir, "BINDIR";
+ push @tries, catdir $self->{MP_AP_PREFIX}, "bin"
+ if exists $self->{MP_AP_PREFIX} and -d $self->{MP_AP_PREFIX};
+ }
+
+ @tries = map { catfile $_, $config } @tries;
+ if (WIN32) {
+ my $ext = '.bat';
+ for (@tries) {
+ $_ .= $ext if ($_ and $_ !~ /$ext$/);
+ }
+ }
+
+ for my $try (@tries) {
+ next unless -x $try;
+ $self->{$key} = $try;
+ }
+ }
+
+ $self->{$key} ||= Apache::TestConfig::which($config);
+
+ # apr_bindir makes sense only if httpd/apr is installed, if we are
+ # building against the source tree we can't link against
+ # apr/aprutil libs
+ unless ($self->httpd_is_source_tree) {
+ $self->{apr_bindir} = $self->{$key}
+ ? dirname $self->{$key}
+ : '';
+ }
+
+ $self->{$key};
+}
+
+sub apr_includedir {
+ my ($self) = @_;
+
+ return $self->{apr_includedir}
+ if $self->{apr_includedir} and -d $self->{apr_includedir};
+
+ my $incdir;
+ my $apr_config_path = $self->apr_config_path;
+
+ if ($apr_config_path) {
+ my $httpd_version = $self->httpd_version;
+ chomp($incdir = `$apr_config_path --includedir`);
+ }
+
+ unless ($incdir and -d $incdir) {
+ # falling back to the default when apr header files are in the
+ # same location as the httpd header files
+ $incdir = $self->ap_includedir;
+ }
+
+ my @tries = ($incdir);
+ if ($self->httpd_is_source_tree) {
+ my $path = catdir $self->dir, "srclib", "apr", "include";
+ push @tries, $path if -d $path;
+ }
+
+
+ for (@tries) {
+ next unless $_ && -e catfile $_, "apr.h";
+ $self->{apr_includedir} = $_;
+ last;
+ }
+
+ unless ($self->{apr_includedir}) {
+ error "Can't find apr include/ directory,",
+ "use MP_APR_CONFIG=/path/to/apr-config";
+ exit 1;
+ }
+
+ $self->{apr_includedir};
+}
+
+#--- parsing apache *.h files ---
+
+sub mmn_eq {
+ my ($class, $dir) = @_;
+
+ return 1 if WIN32; #just assume, till Apache2::Build works under win32
+
+ my $instsrc;
+ {
+ local @INC = grep { !/blib/ } @INC;
+ my $instdir;
+ for (@INC) {
+ last if -d ($instdir = "$_/auto/Apache2/include");
+ }
+ $instsrc = $class->new(dir => $instdir);
+ }
+ my $targsrc = $class->new($dir ? (dir => $dir) : ());
+
+ my $inst_mmn = $instsrc->module_magic_number;
+ my $targ_mmn = $targsrc->module_magic_number;
+
+ unless ($inst_mmn && $targ_mmn) {
+ return 0;
+ }
+ if ($inst_mmn == $targ_mmn) {
+ return 1;
+ }
+ print "Installed MMN $inst_mmn does not match target $targ_mmn\n";
+
+ return 0;
+}
+
+sub module_magic_number {
+ my $self = shift;
+
+ return $self->{mmn} if $self->{mmn};
+
+ my $d = $self->ap_includedir;
+
+ return 0 unless $d;
+
+ #return $mcache{$d} if $mcache{$d};
+ my $fh;
+ for (qw(ap_mmn.h http_config.h)) {
+ last if open $fh, "$d/$_";
+ }
+ return 0 unless $fh;
+
+ my $n;
+ my $mmn_pat = join '|', qw(MODULE_MAGIC_NUMBER_MAJOR MODULE_MAGIC_NUMBER);
+ while(<$fh>) {
+ if(s/^\#define\s+($mmn_pat)\s+(\d+).*/$2/) {
+ chomp($n = $_);
+ last;
+ }
+ }
+ close $fh;
+
+ $self->{mmn} = $n
+}
+
+sub fold_dots {
+ my $v = shift;
+ $v =~ s/\.//g;
+ $v .= '0' if length $v < 3;
+ $v;
+}
+
+sub httpd_version_as_int {
+ my ($self, $dir) = @_;
+ my $v = $self->httpd_version($dir);
+ fold_dots($v);
+}
+
+sub httpd_version_cache {
+ my ($self, $dir, $v) = @_;
+ return '' unless $dir;
+ $self->{httpd_version}->{$dir} = $v if $v;
+ $self->{httpd_version}->{$dir};
+}
+
+sub httpd_version {
+ my ($self, $dir) = @_;
+
+ return unless $dir = $self->ap_includedir($dir);
+
+ if (my $v = $self->httpd_version_cache($dir)) {
+ return $v;
+ }
+
+ my $header = "$dir/ap_release.h";
+ open my $fh, $header or do {
+ error "Unable to open $header: $!";
+ return undef;
+ };
+
+ my $version;
+
+ while (<$fh>) {
+ #now taking bets on how many friggin times this will change
+ #over the course of apache 2.0. 1.3 changed it at least a half
+ #dozen times. hopefully it'll stay in the same file at least.
+ if (/^\#define\s+AP_SERVER_MAJORVERSION\s+\"(\d+)\"/) {
+ #XXX could be more careful here. whatever. see above.
+ my $major = $1;
+ my $minor = (split /\s+/, scalar(<$fh>))[-1];
+ my $patch = (split /\s+/, scalar(<$fh>))[-1];
+ $version = join '.', $major, $minor, $patch;
+ $version =~ s/\"//g;
+ last;
+ }
+ elsif (/^\#define\s+AP_SERVER_BASEREVISION\s+\"(.*)\"/) {
+ $version = $1;
+ last;
+ }
+ elsif(/^\#define\s+AP_SERVER_MAJORVERSION_NUMBER\s+(\d+)/) {
+ # new 2.1 config
+ my $major = $1;
+ my $minor = (split /\s+/, scalar(<$fh>))[-1];
+ my $patch = (split /\s+/, scalar(<$fh>))[-1];
+
+ my ($define, $macro, $dev) = (split /\s+/, scalar(<$fh>));
+
+ if ($macro =~ /AP_SERVER_DEVBUILD_BOOLEAN/ && $dev eq '1') {
+ $dev = "-dev";
+ }
+ else {
+ $dev = "";
+ }
+
+ $version = join '.', $major, $minor, "$patch$dev";
+ $version =~ s/\"//g;
+ last;
+ }
+ }
+
+ close $fh;
+
+ debug "parsed version $version from ap_release.h";
+
+ $self->httpd_version_cache($dir, $version);
+}
+
+my %wanted_apr_config = map { $_, 1} qw(
+ HAS_THREADS HAS_DSO HAS_MMAP HAS_RANDOM HAS_SENDFILE
+ HAS_LARGE_FILES HAS_INLINE HAS_FORK
+);
+
+sub get_apr_config {
+ my $self = shift;
+
+ return $self->{apr_config} if $self->{apr_config};
+
+ my $fh;
+ my $header = catfile $self->apr_includedir, "apr.h";
+ if (WIN32) {
+ open $fh, $header or do {
+ error "Unable to open $header: $!";
+ return undef;
+ };
+ }
+ else {
+ my @command = ($self->perl_config('cpp'), '-E', '-dM', $header);
+ open $fh, '-|', @command or do {
+ error "Unable to preprocess $header with @command: $!";
+ return undef;
+ };
+ }
+
+ my %cfg;
+ while (<$fh>) {
+ next unless s/^\#define\s+APR_((HAVE|HAS|USE)_\w+)/$1/;
+ chomp;
+ my ($name, $val) = split /\s+/, $_, 2;
+ next unless $wanted_apr_config{$name};
+ $val =~ s/\s+$//;
+ next unless $val =~ /^\d+$/;
+ $cfg{$name} = $val;
+ }
+
+ $self->{apr_config} = \%cfg;
+}
+
+#--- generate Makefile ---
+
+sub canon_make_attr {
+ my ($self, $name) = (shift, shift);
+
+ my $attr = join '_', 'MODPERL', uc $name;
+ $self->{$attr} = "@_";
+ "$attr = $self->{$attr}\n\n";
+}
+
+sub xsubpp {
+ my $self = shift;
+ my $xsubpp = join ' ', '$(MODPERL_PERLPATH)',
+ '$(MODPERL_PRIVLIBEXP)/ExtUtils/xsubpp',
+ '-typemap', '$(MODPERL_PRIVLIBEXP)/ExtUtils/typemap';
+
+ my $typemap = $self->file_path('lib/typemap');
+ if (-e $typemap) {
+ $xsubpp .= join ' ',
+ ' -typemap', $typemap;
+ }
+
+ $xsubpp;
+}
+
+sub make_xs {
+ my ($self, $fh) = @_;
+
+ print $fh $self->canon_make_attr(xsubpp => $self->xsubpp);
+
+ return [] unless $self->{XS};
+
+ my @files;
+ my @xs_targ;
+
+ foreach my $name (sort keys %{ $self->{XS} }) {
+ my $xs = $self->{XS}->{$name};
+ #Foo/Bar.xs => Foo_Bar.c
+ (my $c = $xs) =~ s:.*?WrapXS/::;
+ $c =~ s:/:_:g;
+ $c =~ s:\.xs$:.c:;
+
+ push @files, $c;
+
+ push @xs_targ, <<EOF;
+$c: $xs
+\t\$(MODPERL_XSUBPP) $xs > \$*.xsc && \$(MODPERL_MV) \$*.xsc \$@
+
+EOF
+ }
+
+ my %o = (xs_o_files => 'o', xs_o_pic_files => 'lo');
+
+ for my $ext (qw(xs_o_files xs_o_pic_files)) {
+ print $fh $self->canon_make_attr($ext, map {
+ (my $file = $_) =~ s/c$/$o{$ext}/; $file;
+ } @files);
+ }
+
+ print $fh $self->canon_make_attr(xs_clean_files => @files);
+
+ \@xs_targ;
+}
+
+#when we use a bit of MakeMaker, make it use our values for these vars
+my %perl_config_pm_alias = (
+ ABSPERL => 'perlpath',
+ ABSPERLRUN => 'perlpath',
+ PERL => 'perlpath',
+ PERLRUN => 'perlpath',
+ PERL_LIB => 'privlibexp',
+ PERL_ARCHLIB => 'archlibexp',
+);
+
+my $mm_replace = join '|', keys %perl_config_pm_alias;
+
+# get rid of dups
+my %perl_config_pm_alias_values = reverse %perl_config_pm_alias;
+my @perl_config_pm_alias_values = keys %perl_config_pm_alias_values;
+
+my @perl_config_pm = sort(@perl_config_pm_alias_values, qw(cc cpprun
+ rm ranlib lib_ext obj_ext cccdlflags lddlflags optimize));
+
+sub mm_replace {
+ my $val = shift;
+ $$val =~ s/\(($mm_replace)\)/(MODPERL_\U$perl_config_pm_alias{$1})/g;
+}
+
+#help prevent warnings
+my @mm_init_vars = (BASEEXT => '', NAME => '');
+
+sub make_tools {
+ my ($self, $fh) = @_;
+
+ for (@perl_config_pm) {
+ print $fh $self->canon_make_attr($_, $self->perl_config($_));
+ }
+
+ require ExtUtils::MakeMaker;
+ my $mm = bless { @mm_init_vars }, 'MM';
+
+ # Fake initialize MakeMaker
+ foreach my $m (qw(init_main init_others init_tools)) {
+ $mm->$m() if $mm->can($m);
+
+ # init_main() undefines the BASEEXT member which we initialized
+ # to a blank string to prevent warnings; reset it now
+ $mm->{BASEEXT} = '' if not defined $mm->{BASEEXT};
+ }
+
+ for (qw(rm_f mv ld ar cp test_f)) {
+ my $val = $mm->{"\U$_"};
+ if ($val) {
+ mm_replace(\$val);
+ }
+ else {
+ $val = $Config{$_};
+ }
+ print $fh $self->canon_make_attr($_ => $val);
+ }
+}
+
+sub export_files_MSWin32 {
+ my $self = shift;
+ my $xs_dir = $self->file_path("xs");
+ "-def:$xs_dir/modperl.def";
+}
+
+sub export_files_aix {
+ my $self = shift;
+
+ my $Wl = $self->ldopts_prefix;
+ # there are several modperl_*.exp, not just $(BASEEXT).exp
+ # $(BASEEXT).exp resolves to modperl_global.exp
+ my $xs_dir = $self->file_path("xs");
+ join " ", map "${Wl}-bE:$xs_dir/modperl_$_.exp", qw(inline ithreads);
+}
+
+sub dynamic_link_header_default {
+ return <<'EOF';
+$(MODPERL_LIBNAME).$(MODPERL_DLEXT): $(MODPERL_PIC_OBJS)
+ $(MODPERL_RM_F) $@
+ $(MODPERL_LD) $(MODPERL_LDDLFLAGS) \
+ $(MODPERL_AP_LIBS) \
+ $(MODPERL_PIC_OBJS) $(MODPERL_LDOPTS) \
+EOF
+}
+
+sub dynamic_link_default {
+ my $self = shift;
+
+ my $link = $self->dynamic_link_header_default . "\t" . '-o $@';
+
+ my $ranlib = "\t" . '$(MODPERL_RANLIB) $@' . "\n";
+
+ $link .= "\n" . $ranlib unless (DARWIN or OPENBSD);
+
+ $link;
+}
+
+sub dynamic_link_MSWin32 {
+ my $self = shift;
+ my $defs = $self->export_files_MSWin32;
+ my $symbols = $self->modperl_symbols_MSWin32;
+ return $self->dynamic_link_header_default .
+ "\t$defs" .
+ ($symbols ? ' \\' . "\n\t-pdb:$symbols" : '') .
+ ' -out:$@' . "\n\t" .
+ 'if exist $(MODPERL_MANIFEST_LOCATION)' . " \\\n\t" .
+ 'mt /nologo /manifest $(MODPERL_MANIFEST_LOCATION)' . " \\\n\t" .
+ '/outputresource:$@;2' . "\n\n";
+}
+
+sub dynamic_link_aix {
+ my $self = shift;
+ my $link = $self->dynamic_link_header_default .
+ "\t" . $self->export_files_aix . " \\\n" .
+ "\t" . '-o $@' . " \n" .
+ "\t" . '$(MODPERL_RANLIB) $@';
+}
+
+sub dynamic_link_cygwin {
+ my $self = shift;
+ return <<'EOF';
+$(MODPERL_LIBNAME).$(MODPERL_DLEXT): $(MODPERL_PIC_OBJS)
+ $(MODPERL_RM_F) $@
+ $(MODPERL_CC) -shared -o $@ \
+ -Wl,--out-implib=$(MODPERL_LIBNAME).dll.a \
+ -Wl,--export-all-symbols -Wl,--enable-auto-import \
+ -Wl,--enable-auto-image-base -Wl,--stack,8388608 \
+ $(MODPERL_PIC_OBJS) \
+ $(MODPERL_LDDLFLAGS) $(MODPERL_LDOPTS) \
+ $(MODPERL_AP_LIBS)
+ $(MODPERL_RANLIB) $@
+EOF
+}
+
+sub dynamic_link {
+ my $self = shift;
+ my $link = \&{"dynamic_link_$^O"};
+ $link = \&dynamic_link_default unless defined &$link;
+ $link->($self);
+}
+
+# Returns the link flags for the apache shared core library
+my $apache_corelib_cygwin;
+sub apache_corelib_cygwin {
+ return $apache_corelib_cygwin if $apache_corelib_cygwin;
+
+ my $self = shift;
+ my $mp_src = "$self->{cwd}/src/modules/perl";
+ my $core = 'httpd2core';
+
+ # There's a problem with user-installed perl on cygwin.
+ # MakeMaker doesn't know about the .dll.a libs and warns
+ # about missing -lhttpd2core. "Fix" it by copying
+ # the lib and adding .a suffix.
+ # For the static build create a soft link, because libhttpd2core.dll.a
+ # doesn't exist at this time.
+ if ($self->is_dynamic) {
+ my $libpath = $self->apxs(-q => 'exp_libdir');
+ File::Copy::copy("$libpath/lib$core.dll.a", "$mp_src/lib$core.a");
+ } else {
+ my $libpath = catdir($self->{MP_AP_PREFIX}, '.libs');
+ mkdir $libpath unless -d $libpath;
+ qx{touch $libpath/lib$core.dll.a && \
+ ln -fs $libpath/lib$core.dll.a $mp_src/lib$core.a};
+ }
+
+ $apache_corelib_cygwin = "-L$mp_src -l$core";
+}
+
+sub apache_libs_MSWin32 {
+ my $self = shift;
+ my $prefix = $self->apxs(-q => 'PREFIX') || $self->dir;
+ my $lib = catdir $prefix, 'lib';
+ opendir(my $dir, $lib) or die qq{Cannot opendir $lib: $!};
+ my @libs = map {catfile($lib, $_)}
+ grep /^lib(apr|aprutil|httpd)\b\S*?\.lib$/, readdir $dir;
+ closedir $dir;
+ "@libs";
+}
+
+sub apache_libs_cygwin {
+ my $self = shift;
+ join ' ', $self->apache_corelib_cygwin, $self->apru_link_flags;
+}
+
+sub apache_libs {
+ my $self = shift;
+ my $libs = \&{"apache_libs_$^O"};
+ return "" unless defined &$libs;
+ $libs->($self);
+}
+
+sub modperl_libs_MSWin32 {
+ my $self = shift;
+ "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib";
+}
+
+sub modperl_libs_cygwin {
+ my $self = shift;
+ return '' unless $self->is_dynamic;
+ return "-L$self->{cwd}/src/modules/perl -l$self->{MP_LIBNAME}";
+}
+
+sub modperl_libs {
+ my $self = shift;
+ my $libs = \&{"modperl_libs_$^O"};
+ return "" unless defined &$libs;
+ $libs->($self);
+}
+
+sub modperl_libpath_MSWin32 {
+ my $self = shift;
+ # mod_perl.lib will be installed into MP_AP_PREFIX/lib
+ # for use by 3rd party xs modules
+ "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib";
+}
+
+sub modperl_libpath_cygwin {
+ my $self = shift;
+ "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.dll.a";
+}
+
+sub modperl_libpath {
+ my $self = shift;
+ my $libpath = \&{"modperl_libpath_$^O"};
+ return "" unless defined &$libpath;
+ $libpath->($self);
+}
+
+# returns the directory and name of the aprext lib built under blib/
+sub mp_apr_blib {
+ my $self = shift;
+ return unless (my $mp_apr_lib = $self->{MP_APR_LIB});
+ my $lib_mp_apr_lib = 'lib' . $mp_apr_lib;
+ my @dirs = qw(blib arch auto);
+ my $apr_blib = catdir $self->{cwd}, @dirs, $lib_mp_apr_lib;
+ my $full_libname = $lib_mp_apr_lib . $Config{lib_ext};
+ return ($apr_blib, $full_libname);
+}
+
+sub mp_apr_lib_MSWin32 {
+ my $self = shift;
+ # The MP_APR_LIB will be installed into MP_AP_PREFIX/lib
+ # for use by 3rd party xs modules
+ my ($dir, $lib) = $self->mp_apr_blib();
+ $lib =~ s[^lib(\w+)$Config{lib_ext}$][$1];
+ $dir = Win32::GetShortPathName($dir);
+ return qq{ -L$dir -l$lib };
+}
+
+sub mp_apr_lib_cygwin {
+ my $self = shift;
+ my ($dir, $lib) = $self->mp_apr_blib();
+ $lib =~ s[^lib(\w+)$Config{lib_ext}$][$1];
+ my $libs = "-L$dir -l$lib";
+
+ # This is ugly, but is the only way to prevent the "undefined
+ # symbols" error
+ $libs .= join ' ', '',
+ '-L' . catdir($self->perl_config('archlibexp'), 'CORE'), '-lperl';
+
+ $libs;
+}
+
+# linking used for the aprext lib used to build APR/APR::*
+sub mp_apr_lib {
+ my $self = shift;
+ my $libs = \&{"mp_apr_lib_$^O"};
+ return "" unless defined &$libs;
+ $libs->($self);
+}
+
+sub modperl_symbols_MSWin32 {
+ my $self = shift;
+ return "" unless $self->{MP_DEBUG};
+ "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.pdb";
+}
+
+sub modperl_symbols {
+ my $self = shift;
+ my $symbols = \&{"modperl_symbols_$^O"};
+ return "" unless defined &$symbols;
+ $symbols->($self);
+}
+
+sub write_src_makefile {
+ my $self = shift;
+ my $code = ModPerl::Code->new;
+ my $path = $code->path;
+
+ my $install = <<'EOI';
+install:
+EOI
+ if (!$self->should_build_apache) {
+ $install .= <<'EOI';
+# install mod_perl.so
+ @$(MKPATH) $(DESTDIR)$(MODPERL_AP_LIBEXECDIR)
+ $(MODPERL_TEST_F) $(MODPERL_LIB_DSO) && \
+ $(MODPERL_CP) $(MODPERL_LIB_DSO) $(DESTDIR)$(MODPERL_AP_LIBEXECDIR)
+EOI
+ }
+
+ $install .= <<'EOI';
+# install mod_perl .h files
+ @$(MKPATH) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR)
+ $(MODPERL_CP) $(MODPERL_H_FILES) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR)
+EOI
+
+ my $mf = $self->default_file('makefile');
+
+ open my $fh, '>', $mf or die "open $mf: $!";
+
+ print $fh noedit_warning_hash();
+
+ print $fh $self->canon_make_attr('makefile', basename $mf);
+
+ $self->make_tools($fh);
+
+ print $fh $self->canon_make_attr('ap_libs', $self->apache_libs);
+
+ print $fh $self->canon_make_attr('libname', $self->{MP_LIBNAME});
+ print $fh $self->canon_make_attr('dlext', 'so'); #always use .so
+
+ if (AIX) {
+ my $xs_dir = $self->file_path("xs");
+ print $fh "BASEEXT = $xs_dir/modperl_global\n\n";
+ }
+
+ my %libs = (
+ dso => "$self->{MP_LIBNAME}.$self->{MODPERL_DLEXT}",
+ static => "$self->{MP_LIBNAME}$self->{MODPERL_LIB_EXT}",
+ );
+
+ #XXX short-term compat for Apache::TestConfigPerl
+ $libs{shared} = $libs{dso};
+
+ foreach my $type (sort keys %libs) {
+ my $lib = $libs{$type};
+ print $fh $self->canon_make_attr("lib_$type", $libs{$type});
+ }
+
+ if (my $symbols = $self->modperl_symbols) {
+ print $fh $self->canon_make_attr('lib_symbols', $symbols);
+ $install .= <<'EOI';
+# install mod_perl symbol file
+ @$(MKPATH) $(MODPERL_AP_LIBEXECDIR)
+ $(MODPERL_TEST_F) $(MODPERL_LIB_SYMBOLS) && \
+ $(MODPERL_CP) $(MODPERL_LIB_SYMBOLS) $(MODPERL_AP_LIBEXECDIR)
+EOI
+ }
+
+ if ($self->is_dynamic && (my $libs = $self->modperl_libpath)) {
+ print $fh $self->canon_make_attr('lib_location', $libs);
+
+ # Visual Studio 8 on Win32 uses manifest files
+ if (WIN32) {
+ (my $manifest = $libs) =~ s/\.lib$/.so.manifest/;
+ print $fh $self->canon_make_attr('manifest_location', $manifest);
+ }
+
+ print $fh $self->canon_make_attr('ap_libdir',
+ $self->ap_destdir(catdir $self->{MP_AP_PREFIX}, 'lib')
+ );
+
+ $install .= <<'EOI';
+# install mod_perl.lib
+ @$(MKPATH) $(MODPERL_AP_LIBDIR)
+ $(MODPERL_TEST_F) $(MODPERL_LIB_LOCATION) && \
+ $(MODPERL_CP) $(MODPERL_LIB_LOCATION) $(MODPERL_AP_LIBDIR)
+EOI
+ }
+
+ my $libperl = join '/',
+ $self->perl_config('archlibexp'), 'CORE', $self->perl_config('libperl');
+
+ #this is only used for deps, if libperl has changed, relink mod_perl.so
+ #not all perl dists put libperl where it should be, so just leave this
+ #out if it isn't in the proper place
+ if (-e $libperl) {
+ print $fh $self->canon_make_attr('libperl', $libperl);
+ }
+
+ for my $method (qw(ccopts ldopts inc)) {
+ print $fh $self->canon_make_attr($method, $self->$method());
+ }
+
+ for my $method (qw(c_files o_files o_pic_files h_files)) {
+ print $fh $self->canon_make_attr($method, @{ $code->$method() });
+ }
+
+ my @libs;
+ for my $type (sort map { uc } keys %libs) {
+ next unless $self->{"MP_USE_$type"};
+ # on win32 mod_perl.lib must come after mod_perl.so
+ $type eq 'STATIC'
+ ? push @libs, $self->{"MODPERL_LIB_$type"}
+ : unshift @libs, $self->{"MODPERL_LIB_$type"};
+ }
+
+ print $fh $self->canon_make_attr('lib', "@libs");
+
+ print $fh $self->canon_make_attr('AP_INCLUDEDIR',
+ $self->ap_destdir($self->install_headers_dir));
+
+ print $fh $self->canon_make_attr('AP_LIBEXECDIR',
+ $self->ap_destdir($self->apxs(-q => 'LIBEXECDIR')));
+
+ my $xs_targ = $self->make_xs($fh);
+
+ print $fh <<'EOF';
+MODPERL_CCFLAGS = $(MODPERL_INC) $(MODPERL_CCOPTS) $(MODPERL_OPTIMIZE)
+
+MODPERL_CCFLAGS_SHLIB = $(MODPERL_CCFLAGS) $(MODPERL_CCCDLFLAGS)
+
+MODPERL_OBJS = $(MODPERL_O_FILES) $(MODPERL_XS_O_FILES)
+
+MODPERL_PIC_OBJS = $(MODPERL_O_PIC_FILES) $(MODPERL_XS_O_PIC_FILES)
+
+MKPATH = $(MODPERL_PERLPATH) "-MExtUtils::Command" -e mkpath
+
+all: lib
+
+lib: $(MODPERL_LIB)
+
+EOF
+
+ print $fh $install;
+
+ print $fh <<'EOF' if DMAKE;
+
+.USESHELL :
+EOF
+
+ print $fh <<'EOF';
+
+.SUFFIXES: .xs .c $(MODPERL_OBJ_EXT) .lo .i .s
+
+.c.lo:
+ $(MODPERL_CC) $(MODPERL_CCFLAGS_SHLIB) \
+ -c $< && $(MODPERL_MV) $*$(MODPERL_OBJ_EXT) $*.lo
+
+.c$(MODPERL_OBJ_EXT):
+ $(MODPERL_CC) $(MODPERL_CCFLAGS) -c $<
+
+.c.i:
+ $(MODPERL_CPPRUN) $(MODPERL_CCFLAGS) -c $< > $*.i
+
+.c.s:
+ $(MODPERL_CC) -O -S $(MODPERL_CCFLAGS) -c $<
+
+.xs.c:
+ $(MODPERL_XSUBPP) $*.xs >$@
+
+.xs$(MODPERL_OBJ_EXT):
+ $(MODPERL_XSUBPP) $*.xs >$*.c
+ $(MODPERL_CC) $(MODPERL_CCFLAGS) -c $*.c
+
+.xs.lo:
+ $(MODPERL_XSUBPP) $*.xs >$*.c
+ $(MODPERL_CC) $(MODPERL_CCFLAGS_SHLIB) \
+ -c $*.c && $(MODPERL_MV) $*$(MODPERL_OBJ_EXT) $*.lo
+
+clean:
+ $(MODPERL_RM_F) *.a *.so *.xsc \
+ $(MODPERL_LIBNAME).exp $(MODPERL_LIBNAME).lib \
+ *$(MODPERL_OBJ_EXT) *.lo *.i *.s *.pdb *.manifest \
+ $(MODPERL_CLEAN_FILES) \
+ $(MODPERL_XS_CLEAN_FILES)
+
+$(MODPERL_OBJS): $(MODPERL_H_FILES) $(MODPERL_MAKEFILE)
+$(MODPERL_PIC_OBJS): $(MODPERL_H_FILES) $(MODPERL_MAKEFILE)
+$(MODPERL_LIB): $(MODPERL_LIBPERL)
+
+$(MODPERL_LIBNAME)$(MODPERL_LIB_EXT): $(MODPERL_OBJS)
+ $(MODPERL_RM_F) $@
+ $(MODPERL_AR) crv $@ $(MODPERL_OBJS)
+ $(MODPERL_RANLIB) $@
+
+EOF
+
+ print $fh $self->dynamic_link;
+
+ print $fh @$xs_targ;
+
+ print $fh "\n"; # Makefile must end with \n to avoid warnings
+
+ close $fh;
+}
+
+#--- generate MakeMaker parameter values ---
+
+sub otherldflags_default {
+ my $self = shift;
+ # e.g. aix's V:ldflags feeds -brtl and other flags
+ $self->perl_config('ldflags');
+}
+
+sub otherldflags {
+ my $self = shift;
+ my $flags = \&{"otherldflags_$^O"};
+ return $self->otherldflags_default unless defined &$flags;
+ $flags->($self);
+}
+
+sub otherldflags_MSWin32 {
+ my $self = shift;
+ my $flags = $self->otherldflags_default;
+ $flags .= ' -pdb:$(INST_ARCHAUTODIR)\$(BASEEXT).pdb' if $self->{MP_DEBUG};
+ $flags;
+}
+
+sub typemaps {
+ my $self = shift;
+ my @typemaps = ();
+
+ # XXX: could move here the code from ModPerl::BuildMM
+ return [] if IS_MOD_PERL_BUILD;
+
+ # for post install use
+ for (@INC) {
+ # make sure not to pick mod_perl 1.0 typemap
+ my $file = "$_/auto/Apache2/typemap";
+ push @typemaps, $file if -e $file;
+ }
+
+ return \@typemaps;
+}
+
+sub includes {
+ my $self = shift;
+
+ my @inc = ();
+
+ unless (IS_MOD_PERL_BUILD) {
+ # XXX: what if apxs is not available? win32?
+ my $ap_inc = $self->apxs('-q' => 'INCLUDEDIR');
+ if ($ap_inc && -d $ap_inc) {
+ push @inc, $ap_inc;
+ return \@inc;
+ }
+
+ # this is fatal
+ my $reason = $ap_inc
+ ? "path $ap_inc doesn't exist"
+ : "apxs -q INCLUDEDIR didn't return a value";
+ die "Can't find the mod_perl include dir (reason: $reason)";
+ }
+
+ my $os = WIN32 ? 'win32' : 'unix';
+ push @inc, $self->file_path("src/modules/perl", "xs");
+
+ push @inc, $self->mp_include_dir;
+
+ unless ($self->httpd_is_source_tree) {
+ push @inc, $self->apr_includedir;
+
+ my $apuc = $self->apu_config_path;
+ if ($apuc && -x $apuc) {
+ chomp(my $apuincs = qx($apuc --includes));
+ # win32: /Ipath, elsewhere -Ipath
+ $apuincs =~ s{^\s*(-|/)I}{};
+ push @inc, $apuincs;
+ }
+
+ my $ainc = $self->apxs('-q' => 'INCLUDEDIR');
+ if (-d $ainc) {
+ push @inc, $ainc;
+ return \@inc;
+ }
+ }
+
+ if ($self->{MP_AP_PREFIX}) {
+ my $src = $self->dir;
+ for ("$src/modules/perl", "$src/include",
+ "$src/srclib/apr/include",
+ "$src/srclib/apr-util/include",
+ "$src/os/$os")
+ {
+ push @inc, $_ if -d $_;
+ }
+ }
+
+ return \@inc;
+}
+
+sub inc {
+ local $_;
+ my @includes = map { "-I$_" } @{ shift->includes };
+ "@includes";
+}
+
+### Picking the right LFS support flags for mod_perl, by Joe Orton ###
+#
+# on Unix systems where by default off_t is a "long", a 32-bit integer,
+# there are two different ways to get "large file" support, i.e. the
+# ability to manipulate files bigger than 2Gb:
+#
+# 1) you compile using -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64. This
+# makes sys/types.h expose off_t as a "long long", a 64-bit integer, and
+# changes the size of a few other types too. The C library headers
+# automatically arrange to expose a correct implementation of functions
+# like lseek() which take off_t parameters.
+#
+# 2) you compile using -D_LARGEFILE64_SOURCE, and use what is called the
+# "transitional" interface. This means that the system headers expose a
+# new type, "off64_t", which is a long long, but the size of off_t is not
+# changed. A bunch of new functions like lseek64() are exposed by the C
+# library headers, which take off64_t parameters in place of off_t.
+#
+# Perl built with -Duselargefiles uses approach (1).
+#
+# APR HEAD uses (2) by default. APR 0.9 does not by default use either
+# approach, but random users can take a httpd-2.0.49 tarball, and do:
+#
+# export CPPFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+# ./configure
+#
+# to build a copy of apr/httpd which uses approach (1), though this
+# isn't really a supported configuration.
+#
+# The problem that mod_perl has to work around is when you take a
+# package built with approach (1), i.e. Perl, and any package which was
+# *not* built with (1), i.e. APR, and want to interface between
+# them. [1]
+#
+# So what you want to know is whether APR was built using approach (1)
+# or not. APR_HAS_LARGE_FILES in HEAD just tells you whether APR was
+# built using approach (2) or not, which isn't useful in solving this
+# problem.
+#
+# [1]: In some cases, it may be OK to interface between packages which
+# use (1) and packages which use (2). APR HEAD is currently not such a
+# case, since the size of apr_ino_t is still changing when
+# _FILE_OFFSET_BITS is defined.
+#
+# If you want to see how this matters, get some httpd function to do at
+# the very beginning of main():
+#
+# printf("sizeof(request_rec) = %lu, sizeof(apr_finfo_t) = %ul",
+# sizeof(request_rec), sizeof(apr_finfo_t));
+#
+# and then put the same printf in mod_perl somewhere, and see the
+# differences. This is why it is a really terribly silly idea to ever
+# use approach (1) in anything other than an entirely self-contained
+# application.
+#
+# there is no conflict if both libraries either have or don't have
+# large files support enabled
+sub has_large_files_conflict {
+ my $self = shift;
+
+ my $apxs_flags = join $self->apxs_extra_cflags, $self->apxs_extra_cppflags;
+ my $apr_lfs64 = $apxs_flags =~ /-D_FILE_OFFSET_BITS=64/;
+ my $perl_lfs64 = $Config{ccflags} =~ /-D_FILE_OFFSET_BITS=64/;
+
+ # XXX: we don't really deal with the case where APR was built with
+ # -D_FILE_OFFSET_BITS=64 but perl wasn't, since currently we strip
+ # only perl's ccflags, not apr's flags. the reason we don't deal
+ # with it is that we didn't have such a case yet, but may need to
+ # deal with it later
+
+ return 0;
+ # $perl_lfs64 ^ $apr_lfs64;
+}
+
+# if perl is built with uselargefiles, but apr not, the build won't
+# work together as it uses two binary incompatible libraries, so
+# reduce the functionality to the greatest common denominator (C code
+# will have to make sure to prevent any operations that may rely on
+# effects created by uselargefiles, e.g. Off_t=8 instead of Off_t=4)
+sub strip_lfs {
+ my ($self, $cflags) = @_;
+ return $cflags unless $self->has_large_files_conflict();
+
+ my $lf = $Config{ccflags_uselargefiles}
+ || '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64';
+ $cflags =~ s/$lf//;
+ $cflags;
+}
+
+sub define {
+ my $self = shift;
+
+ return "";
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Apache2::Build - Methods for locating and parsing bits of Apache source code
+
+=head1 SYNOPSIS
+
+ use Apache2::Build ();
+ my $build = Apache2::Build->new;
+
+ # rebuild mod_perl with build opts from the previous build
+ % cd modperl-2.0
+ % perl -MApache2::Build -e rebuild
+
+=head1 DESCRIPTION
+
+This module provides methods for locating and parsing bits of Apache
+source code.
+
+Since mod_perl remembers what build options were used to build it, you
+can use this knowledge to rebuild it using the same options. Simply
+chdir to the mod_perl source directory and run:
+
+ % cd modperl-2.0
+ % perl -MApache2::Build -e rebuild
+
+If you want to rebuild not yet installed, but already built mod_perl,
+run from its root directory:
+
+ % perl -Ilib -MApache2::Build -e rebuild
+
+=head1 METHODS
+
+=over 4
+
+=item new
+
+Create an object blessed into the B<Apache2::Build> class.
+
+ my $build = Apache2::Build->new;
+
+=item dir
+
+Top level directory where source files are located.
+
+ my $dir = $build->dir;
+ -d $dir or die "can't stat $dir $!\n";
+
+=item find
+
+Searches for apache source directories, return a list of those found.
+
+Example:
+
+ for my $dir ($build->find) {
+ my $yn = prompt "Configure with $dir ?", "y";
+ ...
+ }
+
+=item inc
+
+Print include paths for MakeMaker's B<INC> argument to
+C<WriteMakefile>.
+
+Example:
+
+ use ExtUtils::MakeMaker;
+
+ use Apache2::Build ();
+
+ WriteMakefile(
+ 'NAME' => 'Apache2::Module',
+ 'VERSION' => '0.01',
+ 'INC' => Apache2::Build->new->inc,
+ );
+
+
+=item module_magic_number
+
+Return the B<MODULE_MAGIC_NUMBER> defined in the apache source.
+
+Example:
+
+ my $mmn = $build->module_magic_number;
+
+=item httpd_version
+
+Return the server version.
+
+Example:
+
+ my $v = $build->httpd_version;
+
+=item otherldflags
+
+Return other ld flags for MakeMaker's B<dynamic_lib> argument to
+C<WriteMakefile>. This might be needed on systems like AIX that need
+special flags to the linker to be able to reference mod_perl or httpd
+symbols.
+
+Example:
+
+ use ExtUtils::MakeMaker;
+
+ use Apache2::Build ();
+
+ WriteMakefile(
+ 'NAME' => 'Apache2::Module',
+ 'VERSION' => '0.01',
+ 'INC' => Apache2::Build->new->inc,
+ 'dynamic_lib' => {
+ 'OTHERLDFLAGS' => Apache2::Build->new->otherldflags,
+ },
+ );
+
+=back
+
+
+=head1 AUTHOR
+
+Doug MacEachern
+
+=cut
diff --git a/2_0_13/lib/Apache2/ParseSource.pm b/2_0_13/lib/Apache2/ParseSource.pm
new file mode 100644
index 0000000..7dada94
--- /dev/null
+++ b/2_0_13/lib/Apache2/ParseSource.pm
@@ -0,0 +1,646 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::ParseSource;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Build ();
+use Config;
+use File::Basename;
+use File::Spec::Functions qw(catdir);
+
+our $VERSION = '0.02';
+
+sub new {
+ my $class = shift;
+
+ my $self = bless {
+ config => Apache2::Build->build_config,
+ @_,
+ }, $class;
+
+ my $prefixes = join '|', @{ $self->{prefixes} || [qw(ap_ apr_)] };
+ $self->{prefix_re} = qr{^($prefixes)};
+
+ $Apache2::Build::APXS ||= $self->{apxs};
+
+ $self;
+}
+
+sub config {
+ shift->{config};
+}
+
+sub parse {
+ my $self = shift;
+
+ $self->{scan_filename} = $self->generate_cscan_file;
+
+ $self->{c} = $self->scan;
+}
+
+sub DESTROY {
+ my $self = shift;
+ unlink $self->{scan_filename}
+}
+
+{
+ package Apache2::ParseSource::Scan;
+
+ our @ISA = qw(ModPerl::CScan);
+
+ sub get {
+ local $SIG{__DIE__} = \&Carp::confess;
+ shift->SUPER::get(@_);
+ }
+}
+
+my @c_scan_defines = (
+ 'CORE_PRIVATE', #so we get all of apache
+ 'MP_SOURCE_SCAN', #so we can avoid some c-scan barfing
+ '_NETINET_TCP_H', #c-scan chokes on netinet/tcp.h
+ '_BYTESWAP_H', #c-scan chokes on byteswap.h
+ '_BITS_BYTESWAP_H', #c-scan chokes on byteswap.h
+ 'Expat_INCLUDED', #c-scan chokes on expath.h
+ # 'APR_OPTIONAL_H', #c-scan chokes on apr_optional.h
+ 'apr_table_do_callback_fn_t=void', #c-scan chokes on function pointers
+);
+
+
+# some types c-scan failing to resolve
+push @c_scan_defines, map { "$_=void" }
+ qw(PPADDR_t PerlExitListEntry modperl_tipool_vtbl_t);
+
+sub scan {
+ require ModPerl::CScan;
+ ModPerl::CScan->VERSION(0.75);
+ require Carp;
+
+ my $self = shift;
+
+ my $c = ModPerl::CScan->new(filename => $self->{scan_filename});
+
+ my $includes = $self->includes;
+
+ # where to find perl headers, but we don't want to parse them otherwise
+ my $perl_core_path = catdir $Config{installarchlib}, "CORE";
+ push @$includes, $perl_core_path;
+
+ $c->set(includeDirs => $includes);
+
+ my @defines = @c_scan_defines;
+
+ unless ($Config{useithreads} and $Config{useithreads} eq 'define') {
+ #fake -DITHREADS so function tables are the same for
+ #vanilla and ithread perls, that is,
+ #make sure THX and friends are always expanded
+ push @defines, 'MP_SOURCE_SCAN_NEED_ITHREADS';
+ }
+
+ $c->set(Defines => join ' ', map "-D$_", @defines);
+
+ bless $c, 'Apache2::ParseSource::Scan';
+}
+
+sub include_dirs {
+ my $self = shift;
+ my $inc = $self->config->apxs('-q' => 'INCLUDEDIR');
+ my @dirs = ($inc, $self->config->mp_include_dir);
+ my $aprinc = $self->config->apxs('-q' => 'APR_INCLUDEDIR');
+
+ unless ($aprinc eq $inc) {
+ # Add APR include directory if different to httpd includedir
+ push @dirs, $aprinc;
+ }
+
+ @dirs;
+}
+
+sub includes { shift->config->includes }
+
+sub find_includes {
+ my $self = shift;
+
+ return $self->{includes} if $self->{includes};
+
+ require File::Find;
+
+ my @includes = ();
+ # don't pick preinstalled mod_perl headers if any, but pick the rest
+ {
+ my @dirs = $self->include_dirs;
+ die "could not find include directory (build the project first)"
+ unless -d $dirs[0];
+
+ my $unwanted = join '|', qw(ap_listen internal version
+ apr_optional mod_include mod_cgi
+ mod_proxy mod_ssl ssl_ apr_anylock
+ apr_rmm ap_config mod_log_config
+ mod_perl modperl_ apreq mod_cache
+ mod_serf mod_dav);
+ $unwanted = qr|^$unwanted|;
+ my $wanted = '';
+
+ push @includes, find_includes_wanted($wanted, $unwanted, @dirs);
+ }
+
+ # now add the live mod_perl headers (to make sure that we always
+ # work against the latest source)
+ {
+ my @dirs = map { catdir $self->config->{cwd}, $_ }
+ catdir(qw(src modules perl)), 'xs';
+
+ my $unwanted = '';
+ my $wanted = join '|', qw(mod_perl modperl_);
+ $wanted = qr|^$wanted|;
+
+ push @includes, find_includes_wanted($wanted, $unwanted, @dirs);
+ }
+
+ # now reorg the header files list, so the fragile scan won't choke
+ my @apr = ();
+ my @mp = ();
+ my @rest = ();
+ for (@includes) {
+ if (/mod_perl.h$/) {
+ # mod_perl.h needs to be included before other mod_perl
+ # headers
+ unshift @mp, $_;
+ }
+ elsif (/modperl_\w+.h$/) {
+ push @mp, $_;
+ }
+ elsif (/apr_\w+\.h$/ ) {
+ # apr headers need to be included first
+ push @apr, $_;
+ }
+ else {
+ push @rest, $_;
+ }
+ }
+ @includes = (@apr, @rest, @mp);
+
+ return $self->{includes} = \@includes;
+}
+
+sub find_includes_wanted {
+ my ($wanted, $unwanted, @dirs) = @_;
+ my @includes = ();
+ for my $dir (@dirs) {
+ File::Find::finddepth({
+ wanted => sub {
+ return unless /\.h$/;
+
+ if ($wanted) {
+ return unless /$wanted/;
+ }
+ else {
+ return if /$unwanted/;
+ }
+
+ my $dir = $File::Find::dir;
+ push @includes, "$dir/$_";
+ },
+ (Apache2::Build::WIN32 ? '' : follow => 1),
+ }, $dir);
+ }
+ return @includes;
+}
+
+sub generate_cscan_file {
+ my $self = shift;
+
+ my $includes = $self->find_includes;
+
+ my $filename = '.apache_includes';
+ open my $fh, '>', $filename or die "can't open $filename: $!";
+
+ for my $path (@$includes) {
+ my $filename = basename $path;
+ print $fh qq(\#include "$path"\n);
+ }
+
+ close $fh;
+
+ return $filename;
+}
+
+my %defines_wanted = (
+ 'Apache2::Const' => {
+ common => [qw{OK DECLINED DONE}],
+ config => [qw{DECLINE_CMD}],
+ context => [qw(NOT_IN_ GLOBAL_ONLY)],
+ http => [qw{HTTP_}],
+ log => [qw(APLOG_)],
+ methods => [qw{M_ METHODS}],
+ mpmq => [qw{AP_MPMQ_}],
+ options => [qw{OPT_}],
+ override => [qw{OR_ EXEC_ON_READ ACCESS_CONF RSRC_CONF}],
+ proxy => [qw{PROXYREQ_}],
+ platform => [qw{CRLF CR LF}],
+ remotehost => [qw{REMOTE_}],
+ satisfy => [qw{SATISFY_}],
+ types => [qw{DIR_MAGIC_TYPE}],
+ auth => [qw{AUTHN_ AUTHZ AP_AUTH_ AUTH_ AUTHZ_}],
+ },
+ 'APR::Const' => {
+ common => [qw{APR_SUCCESS}],
+ error => [qw{APR_E}],
+ filepath => [qw{APR_FILEPATH_}],
+ filetype => [qw{APR_FILETYPE_}],
+ fopen => [qw{APR_FOPEN_}],
+ fprot => [qw{APR_FPROT_}],
+ finfo => [qw{APR_FINFO_}],
+ flock => [qw{APR_FLOCK_}],
+ hook => [qw{APR_HOOK_}],
+ limit => [qw{APR_LIMIT}],
+ poll => [qw{APR_POLL}],
+ socket => [qw{APR_SO_}],
+ status => [qw{APR_TIMEUP}],
+ table => [qw{APR_OVERLAP_TABLES_}],
+ uri => [qw{APR_URI_}],
+ },
+ ModPerl => {
+ common => [qw{MODPERL_RC_}],
+ }
+);
+
+my %defines_wanted_re;
+while (my ($class, $groups) = each %defines_wanted) {
+ while (my ($group, $wanted) = each %$groups) {
+ my $pat = join '|', @$wanted;
+ $defines_wanted_re{$class}->{$group} = $pat; #qr{^($pat)};
+ }
+}
+
+my %enums_wanted = (
+ 'Apache2::Const' => { map { $_, 1 } qw(cmd_how input_mode filter_type conn_keepalive authn_status authz_status) },
+ 'APR::Const' => { map { $_, 1 } qw(apr_shutdown_how apr_read_type apr_lockmech) },
+);
+
+my $defines_unwanted = join '|', qw{
+HTTP_VERSION APR_EOL_STR APLOG_MARK APLOG_NOERRNO APR_SO_TIMEOUT
+APR_HOOK_PROBES_ENABLED APR_HOOK_INT_DCL_UD
+APLOG_MAX_LOGLEVEL
+APR_BEGIN_DECLS APR_END_DECLS
+};
+
+sub get_constants {
+ my ($self) = @_;
+
+ my $includes = $self->find_includes;
+ my (%constants, %seen);
+
+ for my $file (@$includes) {
+ open my $fh, $file or die "open $file: $!";
+ while (<$fh>) {
+ if (s/^\#define\s+(\w+)\s+.*/$1/) {
+ chomp;
+ next if /_H$/;
+ next if $seen{$_}++;
+ $self->handle_constant(\%constants);
+ }
+ elsif (m/enum[^\{]+\{/) {
+ $self->handle_enum($fh, \%constants);
+ }
+ }
+ close $fh;
+ }
+
+ #maintain a few handy shortcuts from 1.xx
+ #aliases are defined in ModPerl::Code
+ push @{ $constants{'Apache2::Const'}->{common} },
+ qw(NOT_FOUND FORBIDDEN AUTH_REQUIRED SERVER_ERROR REDIRECT);
+
+ return \%constants;
+}
+
+sub handle_constant {
+ my ($self, $constants) = @_;
+ my $keys = keys %defines_wanted_re;
+
+ return if /^($defines_unwanted)/o;
+
+ while (my ($class, $groups) = each %defines_wanted_re) {
+ my $keys = keys %$groups;
+
+ while (my ($group, $re) = each %$groups) {
+ next unless /^($re)/;
+ push @{ $constants->{$class}->{$group} }, $_;
+ return;
+ }
+ }
+}
+
+sub handle_enum {
+ my ($self, $fh, $constants) = @_;
+
+ my ($name, $e) = $self->parse_enum($fh);
+ return unless $name;
+
+ $name =~ s/^ap_//;
+ $name =~ s/_(e|t)$//;
+
+ my $class;
+ for (keys %enums_wanted) {
+ next unless $enums_wanted{$_}->{$name};
+ $class = $_;
+ }
+
+ return unless $class;
+ $name =~ s/^apr_//;
+
+ push @{ $constants->{$class}->{$name} }, @$e if $e;
+}
+
+#this should win an award for worlds lamest parser
+sub parse_enum {
+ my ($self, $fh) = @_;
+ my $code = $_;
+ my @e;
+
+ unless ($code =~ /;\s*$/) {
+ local $_;
+ while (<$fh>) {
+ $code .= $_;
+ last if /;\s*$/;
+ }
+ }
+
+ my $name;
+ if ($code =~ s/^\s*enum\s+(\w*)\s*//) {
+ $name = $1;
+ }
+ elsif ($code =~ s/^\s*typedef\s+enum\s+//) {
+ $code =~ s/\s*(\w+)\s*;\s*$//;
+ $name = $1;
+ }
+
+ $code =~ s:/\*.*?\*/::sg;
+ $code =~ s/\s*=\s*\w+//g;
+ $code =~ s/^[^\{]*\{//s;
+ $code =~ s/\}[^;]*;?//s;
+ $code =~ s/^\s*\n//gm;
+
+ while ($code =~ /\b(\w+)\b,?/g) {
+ push @e, $1;
+ }
+
+ return ($name, \@e);
+}
+
+sub wanted_functions { shift->{prefix_re} }
+sub wanted_structures { shift->{prefix_re} }
+
+sub get_functions {
+ my $self = shift;
+
+ my $key = 'parsed_fdecls';
+ return $self->{$key} if $self->{$key};
+
+ my $c = $self->{c};
+
+ my $fdecls = $c->get($key);
+ my $inlines = $c->get('parsed_inlines');
+ push @{$fdecls}, @{$inlines};
+
+ my %seen;
+ my $wanted = $self->wanted_functions;
+
+ my @functions;
+
+ for my $entry (@$fdecls) {
+ my ($rtype, $name, $args) = @$entry;
+ next unless $name =~ $wanted;
+ next if $seen{$name}++;
+ my @attr;
+
+ for (qw(static __inline__)) {
+ if ($rtype =~ s/^($_)\s+//) {
+ push @attr, $1;
+ }
+ }
+
+ #XXX: working around ModPerl::CScan confusion here
+ #macro defines ap_run_error_log causes
+ #cpp filename:linenumber to be included as part of the type
+ for (@$args) {
+ next unless $_->[0];
+ $_->[0] =~ s/^\#.*?\"\s+//;
+ $_->[0] =~ s/^register //;
+ }
+
+ my $func = {
+ name => $name,
+ return_type => $rtype,
+ args => [map {
+ { type => $_->[0], name => $_->[1] }
+ } @$args],
+ };
+
+ $func->{attr} = \@attr if @attr;
+
+ push @functions, $func;
+ }
+
+ # sort the functions by the 'name' attribute to ensure a
+ # consistent output on different systems.
+ $self->{$key} = [sort { $a->{name} cmp $b->{name} } @functions];
+}
+
+sub get_structs {
+ my $self = shift;
+
+ my $key = 'typedef_structs';
+ return $self->{$key} if $self->{$key};
+
+ my $c = $self->{c};
+
+ my $typedef_structs = $c->get($key);
+
+ my %seen;
+ my $wanted = $self->wanted_structures;
+ my $other = join '|', qw(_rec module
+ piped_log uri_t htaccess_result
+ cmd_parms cmd_func cmd_how);
+
+ my @structures;
+ my $sx = qr(^struct\s+);
+
+ while (my ($type, $elts) = each %$typedef_structs) {
+ next unless $type =~ $wanted or $type =~ /($other)$/o;
+
+ $type =~ s/$sx//;
+
+ next if $seen{$type}++;
+
+ my $struct = {
+ type => $type,
+ elts => [map {
+ my $type = $_->[0];
+ $type =~ s/$sx//;
+ $type .= $_->[1] if $_->[1];
+ $type =~ s/:\d+$//; #unsigned:1
+ { type => $type, name => $_->[2] }
+ } @$elts],
+ };
+
+ push @structures, $struct;
+ }
+
+ # sort the structs by the 'type' attribute to ensure a consistent
+ # output on different systems.
+ $self->{$key} = [sort { $a->{type} cmp $b->{type} } @structures];
+}
+
+sub write_functions_pm {
+ my $self = shift;
+ my $file = shift || 'FunctionTable.pm';
+ my $name = shift || 'Apache2::FunctionTable';
+
+ $self->write_pm($file, $name, $self->get_functions);
+}
+
+sub write_structs_pm {
+ my $self = shift;
+ my $file = shift || 'StructureTable.pm';
+ my $name = shift || 'Apache2::StructureTable';
+
+ $self->write_pm($file, $name, $self->get_structs);
+}
+
+sub write_constants_pm {
+ my $self = shift;
+ my $file = shift || 'ConstantsTable.pm';
+ my $name = shift || 'Apache2::ConstantsTable';
+
+ $self->write_pm($file, $name, $self->get_constants);
+}
+
+sub write_pm {
+ my ($self, $file, $name, $data) = @_;
+
+ require Data::Dumper;
+ local $Data::Dumper::Indent = 1;
+
+ my ($subdir) = (split '::', $name)[0];
+
+ my $tdir = '';
+ my $build = Apache2::Build->new(init => 1);
+ my $httpd_version = $build->httpd_version;
+ if ($httpd_version lt '2.4.0') {
+ $tdir='xs/tables/current';
+ }
+ else {
+ $tdir='xs/tables/current24';
+ }
+
+ if (-d "$tdir/$subdir") {
+ $file = "$tdir/$subdir/$file";
+ }
+
+ # sort the hashes (including nested ones) for a consistent dump
+ canonsort(\$data);
+
+ my $dump = Data::Dumper->new([$data],
+ [$name])->Dump;
+
+ my $package = ref($self) || $self;
+ my $version = $self->VERSION;
+ my $date = scalar localtime;
+
+ my $new_content = << "EOF";
+package $name;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by $package/$version
+# ! $date
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$dump
+
+1;
+EOF
+
+ my $old_content = '';
+ if (-e $file) {
+ open my $pm, '<', $file or die "open $file: $!";
+ local $/ = undef; # slurp the file
+ $old_content = <$pm>;
+ close $pm;
+ }
+
+ my $overwrite = 1;
+ if ($old_content) {
+ # strip the date line, which will never be the same before
+ # comparing
+ my $table_header = qr{^\#\s!.*};
+ (my $old = $old_content) =~ s/$table_header//mg;
+ (my $new = $new_content) =~ s/$table_header//mg;
+ $overwrite = 0 if $old eq $new;
+ }
+
+ if ($overwrite) {
+ open my $pm, '>', $file or die "open $file: $!";
+ print $pm $new_content;
+ close $pm;
+ }
+
+}
+
+# canonsort(\$data);
+# sort nested hashes in the data structure.
+# the data structure itself gets modified
+
+sub canonsort {
+ my $ref = shift;
+ my $type = ref $$ref;
+
+ return unless $type;
+
+ require Tie::IxHash;
+
+ my $data = $$ref;
+
+ if ($type eq 'ARRAY') {
+ for (@$data) {
+ canonsort(\$_);
+ }
+ }
+ elsif ($type eq 'HASH') {
+ for (keys %$data) {
+ canonsort(\$data->{$_});
+ }
+
+ tie my %ixhash, 'Tie::IxHash';
+
+ # reverse sort so we get the order of:
+ # return_type, name, args { type, name } for functions
+ # type, elts { type, name } for structures
+
+ for (sort { $b cmp $a } keys %$data) {
+ $ixhash{$_} = $data->{$_};
+ }
+
+ $$ref = \%ixhash;
+ }
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/Apache2/PerlSections.pm b/2_0_13/lib/Apache2/PerlSections.pm
new file mode 100644
index 0000000..69cd6b8
--- /dev/null
+++ b/2_0_13/lib/Apache2/PerlSections.pm
@@ -0,0 +1,233 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::PerlSections;
+
+use strict;
+use warnings FATAL => 'all';
+
+our $VERSION = '2.00';
+
+use Apache2::CmdParms ();
+use Apache2::Directive ();
+use APR::Table ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Const -compile => qw(OK);
+
+use constant SPECIAL_NAME => 'PerlConfig';
+use constant SPECIAL_PACKAGE => 'Apache2::ReadConfig';
+
+sub new {
+ my ($package, @args) = @_;
+ return bless { @args }, ref($package) || $package;
+}
+
+sub parms { return shift->{'parms'} }
+sub directives { return shift->{'directives'} ||= [] }
+sub package { return shift->{'args'}->{'package'} }
+
+my @saved;
+sub save { return $Apache2::PerlSections::Save }
+sub server { return $Apache2::PerlSections::Server }
+sub saved { return @saved }
+
+sub handler : method {
+ my ($self, $parms, $args) = @_;
+
+ unless (ref $self) {
+ $self = $self->new('parms' => $parms, 'args' => $args);
+ }
+
+ if ($self->save) {
+ push @saved, $self->package;
+ }
+
+ my $special = $self->SPECIAL_NAME;
+
+ for my $entry ($self->symdump()) {
+ if ($entry->[0] !~ /$special/) {
+ $self->dump_any(@$entry);
+ }
+ }
+
+ {
+ no strict 'refs';
+ foreach my $package ($self->package) {
+ my @config = map { split /\n/ }
+ grep { defined }
+ (@{"${package}::$special"},
+ ${"${package}::$special"});
+ $self->dump_special(@config);
+ }
+ }
+
+ $self->post_config();
+
+ Apache2::Const::OK;
+}
+
+my %directives_seen_hack;
+
+sub symdump {
+ my ($self) = @_;
+
+ unless ($self->{symbols}) {
+ no strict;
+
+ $self->{symbols} = [];
+
+ #XXX: Here would be a good place to warn about NOT using
+ # Apache2::ReadConfig:: directly in <Perl> sections
+ foreach my $pack ($self->package, $self->SPECIAL_PACKAGE) {
+ #XXX: Shamelessly borrowed from Devel::Symdump;
+ while (my ($key, $val) = each(%{ *{"$pack\::"} })) {
+ #We don't want to pick up stashes...
+ next if ($key =~ /::$/);
+ local (*ENTRY) = $val;
+ if (defined $val && defined *ENTRY{SCALAR} && defined $ENTRY) {
+ push @{$self->{symbols}}, [$key, $ENTRY];
+ }
+ if (defined $val && defined *ENTRY{ARRAY}) {
+ unless (exists $directives_seen_hack{"$key$val"}) {
+ $directives_seen_hack{"$key$val"} = 1;
+ push @{$self->{symbols}}, [$key, \@ENTRY];
+ }
+ }
+ if (defined $val && defined *ENTRY{HASH} && $key !~ /::/) {
+ push @{$self->{symbols}}, [$key, \%ENTRY];
+ }
+ }
+ }
+ }
+
+ return @{$self->{symbols}};
+}
+
+sub dump_special {
+ my ($self, @data) = @_;
+ $self->add_config(@data);
+}
+
+sub dump_any {
+ my ($self, $name, $entry) = @_;
+ my $type = ref $entry;
+
+ if ($type eq 'ARRAY') {
+ $self->dump_array($name, $entry);
+ }
+ elsif ($type eq 'HASH') {
+ $self->dump_hash($name, $entry);
+ }
+ else {
+ $self->dump_entry($name, $entry);
+ }
+}
+
+sub dump_hash {
+ my ($self, $name, $hash) = @_;
+
+ for my $entry (keys %{ $hash || {} }) {
+ my $item = $hash->{$entry};
+ my $type = ref($item);
+
+ if ($type eq 'HASH') {
+ $self->dump_section($name, $entry, $item);
+ }
+ elsif ($type eq 'ARRAY') {
+ for my $e (@$item) {
+ $self->dump_section($name, $entry, $e);
+ }
+ }
+ }
+}
+
+sub dump_section {
+ my ($self, $name, $loc, $hash) = @_;
+
+ $self->add_config("<$name $loc>\n");
+
+ for my $entry (keys %{ $hash || {} }) {
+ $self->dump_entry($entry, $hash->{$entry});
+ }
+
+ $self->add_config("</$name>\n");
+}
+
+sub dump_array {
+ my ($self, $name, $entries) = @_;
+
+ for my $entry (@$entries) {
+ $self->dump_entry($name, $entry);
+ }
+}
+
+sub dump_entry {
+ my ($self, $name, $entry) = @_;
+ my $type = ref $entry;
+
+ if ($type eq 'SCALAR') {
+ $self->add_config("$name $$entry\n");
+ }
+ elsif ($type eq 'ARRAY') {
+ if (grep {ref} @$entry) {
+ $self->dump_entry($name, $_) for @$entry;
+ }
+ else {
+ $self->add_config("$name @$entry\n");
+ }
+ }
+ elsif ($type eq 'HASH') {
+ $self->dump_hash($name, $entry);
+ }
+ elsif ($type) {
+ #XXX: Could do $type->can('httpd_config') here on objects ???
+ die "Unknown type '$type' for directive $name";
+ }
+ elsif (defined $entry) {
+ $self->add_config("$name $entry\n");
+ }
+}
+
+sub add_config {
+ my ($self, @config) = @_;
+ foreach my $config (@config) {
+ return unless defined $config;
+ chomp($config);
+ push @{ $self->directives }, $config;
+ }
+}
+
+sub post_config {
+ my ($self) = @_;
+ my $errmsg = $self->parms->add_config($self->directives);
+ die $errmsg if $errmsg;
+}
+
+sub dump {
+ my $class = shift;
+ require Apache2::PerlSections::Dump;
+ return Apache2::PerlSections::Dump->dump(@_);
+}
+
+sub store {
+ my $class = shift;
+ require Apache2::PerlSections::Dump;
+ return Apache2::PerlSections::Dump->store(@_);
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/Apache2/PerlSections/Dump.pm b/2_0_13/lib/Apache2/PerlSections/Dump.pm
new file mode 100644
index 0000000..4366410
--- /dev/null
+++ b/2_0_13/lib/Apache2/PerlSections/Dump.pm
@@ -0,0 +1,101 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::PerlSections::Dump;
+
+use strict;
+use warnings FATAL => 'all';
+
+our $VERSION = '0.01';
+
+use Apache2::PerlSections;
+our @ISA = qw(Apache2::PerlSections);
+
+use Data::Dumper;
+
+# Process all saved packages
+sub package { return shift->saved }
+
+# We don't want to save anything
+sub save { return }
+
+# We don't want to post any config to apache, we are dumping
+sub post_config { return }
+
+sub dump {
+ my $self = shift;
+ unless (ref $self) {
+ $self = $self->new;
+ }
+ $self->handler();
+ return join "\n", @{$self->directives}, '1;', '__END__', '';
+}
+
+sub store {
+ my ($class, $filename) = @_;
+ require IO::File;
+
+ my $fh = IO::File->new(">$filename") or die "can't open $filename $!\n";
+
+ $fh->print($class->dump);
+
+ $fh->close;
+}
+
+sub dump_array {
+ my ($self, $name, $entry) = @_;
+ $self->add_config(Data::Dumper->Dump([$entry], ["*$name"]));
+}
+
+sub dump_hash {
+ my ($self, $name, $entry) = @_;
+ for my $elem (sort keys %{$entry}) {
+ $self->add_config(Data::Dumper->Dump([$entry->{$elem}],
+ ["\$$name"."{'$elem'}"]));
+ }
+
+}
+
+sub dump_entry {
+ my ($self, $name, $entry) = @_;
+
+ return if not defined $entry;
+ my $type = ref($entry);
+
+ if ($type eq 'SCALAR') {
+ $self->add_config(Data::Dumper->Dump([$$entry],[$name]));
+ }
+ if ($type eq 'ARRAY') {
+ $self->dump_array($name,$entry);
+ }
+ else {
+ $self->add_config(Data::Dumper->Dump([$entry],[$name]));
+ }
+}
+
+sub dump_special {
+ my ($self, @data) = @_;
+
+ my @dump = grep { defined } @data;
+ return unless @dump;
+
+ $self->add_config(Data::Dumper->Dump([\@dump],['*'.$self->SPECIAL_NAME]));
+}
+
+
+
+1;
+__END__
diff --git a/2_0_13/lib/Apache2/Resource.pm b/2_0_13/lib/Apache2/Resource.pm
new file mode 100644
index 0000000..ccf70d9
--- /dev/null
+++ b/2_0_13/lib/Apache2/Resource.pm
@@ -0,0 +1,150 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+package Apache2::Resource;
+
+use strict;
+use warnings FATAL => 'all';
+
+use mod_perl2;
+
+use Apache2::Module ();
+
+use BSD::Resource qw(setrlimit getrlimit get_rlimits);
+
+use Apache2::Const -compile => qw(OK);
+
+$Apache2::Resource::VERSION = '1.72';
+
+our $Debug;
+
+$Debug ||= 0;
+
+sub MB ($) {
+ my $num = shift;
+ return ($num < (1024 * 1024)) ? $num*1024*1024 : $num;
+}
+
+sub BM ($) {
+ my $num = shift;
+ return ($num > (1024 * 1024)) ? '(' . ($num>>20) . 'Mb)' : '';
+}
+
+sub DEFAULT_RLIMIT_DATA () { 64 } # data (memory) size in MB
+sub DEFAULT_RLIMIT_AS () { 64 } # address space (memory) size in MB
+sub DEFAULT_RLIMIT_CPU () { 60*6 } # cpu time in seconds
+sub DEFAULT_RLIMIT_CORE () { 0 } # core file size (MB)
+sub DEFAULT_RLIMIT_RSS () { 16 } # resident set size (MB)
+sub DEFAULT_RLIMIT_FSIZE () { 10 } # file size (MB)
+sub DEFAULT_RLIMIT_STACK () { 20 } # stack size (MB)
+
+my %is_mb = map {$_, 1} qw{DATA RSS STACK FSIZE CORE MEMLOCK AS};
+
+sub debug { print STDERR @_ if $Debug }
+
+sub install_rlimit ($$$) {
+ my ($res, $soft, $hard) = @_;
+
+ my $name = $res;
+
+ my $cv = \&{"BSD::Resource::RLIMIT_${res}"};
+ eval { $res = $cv->() };
+ return if $@;
+
+ unless ($soft) {
+ my $defval = \&{"DEFAULT_RLIMIT_${name}"};
+ if (defined &$defval) {
+ $soft = $defval->();
+ } else {
+ warn "can't find default for `$defval'\n";
+ }
+ }
+
+ $hard ||= $soft;
+
+ debug "Apache2::Resource: PID $$ attempting to set `$name'=$soft:$hard ...";
+
+ ($soft, $hard) = (MB $soft, MB $hard) if $is_mb{$name};
+
+ return setrlimit $res, $soft, $hard;
+}
+
+sub handler {
+ while (my ($k, $v) = each %ENV) {
+ next unless $k =~ /^PERL_RLIMIT_(\w+)$/;
+ $k = $1;
+ next if $k eq "DEFAULTS";
+ my ($soft, $hard) = split ":", $v, 2;
+ $hard ||= $soft;
+
+ my $set = install_rlimit $k, $soft, $hard;
+ debug "not " unless $set;
+ debug "ok\n";
+ debug $@ if $@;
+ }
+
+ Apache2::Const::OK;
+}
+
+sub default_handler {
+ while (my ($k, $v) = each %Apache2::Resource::) {
+ next unless $k =~ s/^DEFAULT_/PERL_/;
+ $ENV{$k} = "";
+ }
+ handler();
+}
+
+sub status_rlimit {
+ my $lim = get_rlimits();
+ my @retval = ("<table border=1><tr>",
+ (map "<th>$_</th>", qw(Resource Soft Hard)),
+ "</tr>");
+
+ for my $res (keys %$lim) {
+ my ($soft, $hard) = getrlimit($lim->{$res});
+ (my $limit = $res) =~ s/^RLIMIT_//;
+ ($soft, $hard) = ("$soft " . BM($soft), "$hard ". BM($hard))
+ if $is_mb{$limit};
+ push @retval,
+ "<tr>", (map { "<td>$_</td>" } $res, $soft, $hard), "</tr>\n";
+ }
+
+ push @retval, "</table><P>";
+ push @retval, "<small>Apache2::Resource $Apache2::Resource::VERSION</small>";
+
+ return \@retval;
+}
+
+if ($ENV{MOD_PERL}) {
+ if ($ENV{PERL_RLIMIT_DEFAULTS}) {
+ require Apache2::ServerUtil;
+ Apache2::ServerUtil->server->push_handlers(
+ PerlChildInitHandler => \&default_handler);
+ }
+
+ Apache2::Status->menu_item(rlimit => "Resource Limits",
+ \&status_rlimit)
+ if Apache2::Module::loaded("Apache2::Status");
+}
+
+# perl Apache2/Resource.pm
+++$Debug, default_handler unless caller();
+
+1;
+
+__END__
+
diff --git a/2_0_13/lib/Apache2/SourceTables.pm b/2_0_13/lib/Apache2/SourceTables.pm
new file mode 100644
index 0000000..b82ba13
--- /dev/null
+++ b/2_0_13/lib/Apache2/SourceTables.pm
@@ -0,0 +1,32 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::SourceTables;
+
+use Apache2::StructureTable ();
+use Apache2::FunctionTable ();
+
+#build hash versions of the tables
+%Apache2::StructureTable =
+ map { $_->{type}, $_->{elts} } @$Apache2::StructureTable;
+
+%Apache2::FunctionTable =
+ map { $_->{name}, {elts => $_->{elts},
+ return_type => $_->{return_type} } }
+ @$Apache2::FunctionTable;
+
+1;
+__END__
diff --git a/2_0_13/lib/Apache2/Status.pm b/2_0_13/lib/Apache2/Status.pm
new file mode 100644
index 0000000..ee4bb8c
--- /dev/null
+++ b/2_0_13/lib/Apache2/Status.pm
@@ -0,0 +1,911 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::Status;
+
+use strict;
+use warnings FATAL => 'all';
+
+use mod_perl2;
+
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::ServerUtil ();
+
+use File::Spec ();
+
+use Apache2::Const -compile => qw(OK);
+
+$Apache2::Status::VERSION = '4.01'; # mod_perl 2.0
+
+use constant IS_WIN32 => ($^O eq "MSWin32");
+
+my %status = (
+ script => "PerlRequire'd Files",
+ inc => "Loaded Modules",
+ rgysubs => "Compiled Registry Scripts",
+ symdump => "Symbol Table Dump",
+ inh_tree => "Inheritance Tree",
+ isa_tree => "ISA Tree",
+ env => "Environment",
+ sig => "Signal Handlers",
+ myconfig => "Perl Configuration",
+);
+delete $status{'sig'} if IS_WIN32;
+
+if ($Apache2::PerlSections::Save) {
+ $status{"section_config"} = "Perl Section Configuration";
+}
+
+my %requires = (
+ deparse => ["StatusDeparse", "B::Deparse", 0.59, ],
+ fathom => ["StatusFathom", "B::Fathom", 0.05, ],
+ symdump => ["", "Devel::Symdump", 2.00, ],
+ dumper => ["StatusDumper", "Data::Dumper", 0, ],
+ b => ["", "B", 0, ],
+ graph => ["StatusGraph", "B::Graph", 0.03, ],
+ lexinfo => ["StatusLexInfo", "B::LexInfo", 0, ],
+ xref => ["StatusXref", "B::Xref", 1.01, ],
+ terse => ["StatusTerse", "B::Terse", 0, ],
+ tersesize => ["StatusTerseSize", "B::TerseSize", 0.09, ],
+ packagesize => ["StatusPackageSize", "B::TerseSize", 0.09, ],
+ peek => ["StatusPeek", "Apache::Peek", 1.03, ],
+);
+
+sub has {
+ my ($r, $what) = @_;
+
+ return 0 unless exists $requires{$what};
+
+ my ($opt, $module, $version) = @{ $requires{$what} };
+
+ (my $file = $module) =~ s|::|/|;
+ $file .= ".pm";
+
+ # if !$opt we skip the testing for the option
+ return 0 if $opt && !status_config($r, $opt);
+ return 0 unless eval { require $file };
+ my $mod_ver = $module->VERSION;
+ $mod_ver =~ s/_.*//; # handle dev versions like 2.121_02
+ return 0 unless $mod_ver && $mod_ver >= $version;
+
+ return 1;
+}
+
+use constant CPAN_SEARCH => 'http://search.cpan.org/search?mode=module;query';
+
+sub install_hint {
+ my ($module) = @_;
+ return qq{<p>Please install the } .
+ qq{<a href="@{[CPAN_SEARCH]}=$module">$module</a> module.</p>};
+}
+
+sub status_config {
+ my ($r, $key) = @_;
+ return (lc($r->dir_config($key) || '') eq "on") ||
+ (lc($r->dir_config('StatusOptionsAll') || '') eq "on");
+}
+
+sub menu_item {
+ my ($self, $key, $val, $sub) = @_;
+ $status{$key} = $val;
+ no strict;
+ no warnings 'redefine';
+ *{"status_${key}"} = $sub if $sub and ref $sub eq 'CODE';
+}
+
+sub handler {
+ my ($r) = @_;
+ my $qs = $r->args || "";
+ my $sub = "status_$qs";
+ no strict 'refs';
+
+ if ($qs =~ s/^(noh_\w+).*/$1/) {
+ &{$qs}($r);
+ return Apache2::Const::OK;
+ }
+
+ header($r);
+ if (defined &$sub) {
+ $r->print(@{ &{$sub}($r) });
+ }
+ elsif ($qs and %{$qs."::"}) {
+ $r->print(symdump($r, $qs));
+ }
+ else {
+ my $uri = $r->location;
+ $r->print('<p>');
+ $r->print(
+ map { qq[<a href="$uri?$_">$status{$_}</a><br />\n] } sort { lc $a cmp lc $b } keys %status
+ );
+ $r->print('</p>');
+ }
+ $r->print("</body></html>");
+
+ Apache2::Const::OK;
+}
+
+sub header {
+ my $r = shift;
+ my $start = scalar localtime $^T;
+ my $srv = Apache2::ServerUtil::get_server_banner();
+ $r->content_type("text/html");
+ my $v = $^V ? sprintf "v%vd", $^V : $];
+ $r->print(<<"EOF");
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Apache2::Status $Apache2::Status::VERSION</title>
+ <style type="text/css">
+ body {
+ color: #000;
+ background-color: #fff;
+ }
+ p.hdr {
+ background-color: #ddd;
+ border: 2px outset;
+ padding: 3px;
+ width: 99%;
+ }
+ </style>
+ </head>
+ <body>
+ <p class="hdr">
+ Embedded Perl version <b>$v</b> for <b>$srv</b> process <b>$$</b>,<br />
+ running since $start
+ </p>
+EOF
+
+}
+
+sub symdump {
+ my ($r, $package) = @_;
+
+ return install_hint("Devel::Symdump") unless has($r, "symdump");
+
+ # lc generates a (FATAL) warning if $r->dir_config is undef
+ my $meth = lc($r->dir_config("StatusRdump") || '') eq "on"
+ ? "rnew" : "new";
+ my $sob = Devel::Symdump->$meth($package);
+ return $sob->Apache2::Status::as_HTML($package, $r);
+}
+
+sub status_symdump {
+ my ($r) = @_;
+ [symdump($r, 'main')];
+}
+
+sub status_section_config {
+ my ($r) = @_;
+ require Apache2::PerlSections;
+ ["<pre>", Apache2::PerlSections->dump, "</pre>"];
+}
+
+sub status_inc {
+ my ($r) = @_;
+
+ my $uri = $r->location;
+ my @retval = (
+ '<table border="1">',
+ "<tr>",
+ (map "<td><b>$_</b></td>", qw(Package Version Modified File)),
+ "</tr>\n"
+ );
+
+ foreach my $file (sort keys %INC) {
+ local $^W = 0;
+ next if $file =~ m:^/:;
+ next unless $file =~ m:\.pm:;
+ next unless $INC{$file}; #e.g. fake Apache2/TieHandle.pm
+
+ no strict 'refs';
+ (my $module = $file) =~ s,/,::,g;
+ $module =~ s,\.pm$,,;
+ next if $module eq 'mod_perl';
+ my $v = ${"$module\:\:VERSION"} || '0.00';
+ my $mtime = -e $INC{$file} ? scalar localtime((stat $INC{$file})[9]) :
+ 'N/A';
+
+ push @retval, (
+ "<tr>",
+ (map "<td>$_</td>",
+ qq(<a href="$uri?$module">$module</a>),
+ $v, $mtime, $INC{$file}),
+ "</tr>\n"
+ );
+ }
+ push @retval, "</table>\n";
+ push @retval, "<p><b>\@INC</b> = <br />", join "<br />\n", @INC, "";
+ \@retval;
+}
+
+sub status_script {
+ my ($r) = @_;
+
+ my @retval = (
+ '<table border="1">',
+ "<tr><td><b>PerlRequire</b></td><td><b>Location</b></td></tr>\n",
+ );
+
+ foreach my $file (sort keys %INC) {
+ next if $file =~ m:\.(pm|al|ix)$:;
+ push @retval,
+ qq(<tr><td>$file</td><td>$INC{$file}</td></tr>\n);
+ }
+ push @retval, "</table>";
+ \@retval;
+}
+
+my $RegistryCache;
+
+sub registry_cache {
+ my ($self, $cache) = @_;
+
+ # XXX: generalize
+
+ $RegistryCache = $cache if $cache;
+ $RegistryCache || $Apache2::Registry;
+}
+
+sub get_packages_per_handler {
+ my ($root, $stash) = @_;
+
+ my %handlers = ();
+ my @packages = get_packages($stash);
+ for (@packages) {
+ /^\*${root}::([\w:]+)::(\w+)::$/ && push @{ $handlers{$1} }, $2;
+ }
+
+ return %handlers;
+}
+
+sub get_packages {
+ my ($stash) = @_;
+
+ no strict 'refs';
+ my @packages = ();
+ for (keys %$stash) {
+ return $stash unless $stash->{$_} =~ /::$/;
+ push @packages, get_packages($stash->{$_});
+ }
+ return @packages;
+}
+
+sub status_rgysubs {
+ my ($r) = @_;
+
+ local $_;
+ my $uri = $r->location;
+ my $cache = __PACKAGE__->registry_cache;
+
+ my @retval = "<h2>Compiled registry scripts grouped by their handler</h2>";
+
+ push @retval,
+ "<p><b>Click on package name to see its symbol table</b></p>\n";
+
+ my $root = "ModPerl::ROOT";
+ no strict 'refs';
+ my %handlers = get_packages_per_handler($root, *{$root . "::"});
+ for my $handler (sort keys %handlers) {
+ push @retval, "<h4>$handler:</h4>\n<p>\n";
+ for (sort @{ $handlers{$handler} }) {
+ my $full = join '::', $root, $handler, $_;
+ push @retval, qq(<a href="$uri?$full">$_</a>\n), "<br />";
+ }
+ push @retval, "</p>\n";
+ }
+
+ \@retval;
+}
+
+sub status_env {
+ my ($r) = shift;
+
+ my @retval = ("<p>\n");
+
+ if ($r->handler eq 'modperl') {
+ # the handler can be executed under the "modperl" handler
+ push @retval,
+ qq{<b>Under the "modperl" handler, the environment is</b>:};
+ # XXX: I guess we could call $r->subprocess_env; and show how
+ # would it look like under the 'perl-script' environment, but
+ # under the 'modperl' handler %ENV doesn't get reset,
+ # therefore on the first reload it'll see the bloated %ENV in
+ # first place.
+ } else {
+ # the handler can be executed under the "perl-script" handler
+ push @retval,
+ qq{<b>Under the "perl-script" handler, the environment is</b>:};
+ }
+ push @retval, "\n</p>\n";
+ push @retval, "<pre>",
+ (map "$_ = " . escape_html($ENV{$_}||'') . "\n",
+ sort keys %ENV), "</pre>";
+
+ \@retval;
+}
+
+sub status_sig {
+ ["<pre>",
+ (map {
+ my $val = $SIG{$_} || "";
+ if ($val and ref $val eq "CODE") {
+ # XXX: 2.0 doesn't have Apache2::Symbol
+ if (my $cv = Apache2::Symbol->can('sv_name')) {
+ $val = "\\&". $cv->($val);
+ }
+ }
+ "$_ = $val\n" }
+ sort keys %SIG),
+ "</pre>"];
+}
+
+sub status_myconfig {
+ ["<pre>", myconfig(), "</pre>"];
+}
+
+sub status_inh_tree {
+ return has(shift, "symdump")
+ ? ["<pre>", Devel::Symdump->inh_tree, "</pre>"]
+ : install_hint("Devel::Symdump");
+}
+
+sub status_isa_tree {
+ return has(shift, "symdump")
+ ? ["<pre>", Devel::Symdump->isa_tree, "</pre>"]
+ : install_hint("Devel::Symdump");
+}
+
+sub status_data_dump {
+ my ($r) = @_;
+
+ return install_hint('Data::Dumper') unless has($r, "dumper");
+
+ my ($name, $type) = (split "/", $r->uri)[-2,-1];
+
+ no strict 'refs';
+ my @retval = "<p>\nData Dump of $name $type\n</p>\n<pre>\n";
+ my $str = Data::Dumper->Dump([*$name{$type}], ['*'.$name]);
+ $str = escape_html($str);
+ $str =~ s/= \\/= /; #whack backwack
+ push @retval, $str, "\n";
+ push @retval, peek_link($r, $name, $type);
+ push @retval, b_graph_link($r, $name);
+ push @retval, "</pre>";
+ \@retval;
+}
+
+sub cv_file {
+ my $obj = shift;
+ $obj->can('FILEGV') ? $obj->FILEGV->SV->PV : $obj->FILE;
+}
+
+sub status_cv_dump {
+ my ($r) = @_;
+ return [] unless has($r, "b");
+
+ no strict 'refs';
+ my ($name, $type) = (split "/", $r->uri)[-2,-1];
+ # could be another child, which doesn't have this symbol table?
+ return unless *$name{CODE};
+
+ my @retval = "<p>Subroutine info for <b>$name</b></p>\n<pre>\n";
+ my $obj = B::svref_2object(*$name{CODE});
+ my $file = cv_file($obj);
+ my $stash = $obj->GV->STASH->NAME;
+ my $script = $r->location;
+
+ push @retval, "File: ",
+ (-e $file ? qq(<a href="file:$file">$file</a>) : $file), "\n";
+
+ my $cv = $obj->GV->CV;
+ my $proto = $cv->PV if $cv->can('PV');
+
+ push @retval, qq(Package: <a href="$script?$stash">$stash</a>\n);
+ push @retval, "Line: ", $obj->GV->LINE, "\n";
+ push @retval, "Prototype: ", $proto || "none", "\n";
+ push @retval, "XSUB: ", $obj->XSUB ? "yes" : "no", "\n";
+ push @retval, peek_link($r, $name, $type);
+ push @retval, b_graph_link($r, $name);
+ push @retval, xref_link($r, $name);
+ push @retval, b_lexinfo_link($r, $name);
+ push @retval, b_terse_link($r, $name);
+ push @retval, b_terse_size_link($r, $name);
+ push @retval, b_deparse_link($r, $name);
+ push @retval, b_fathom_link($r, $name);
+ push @retval, "</pre>";
+ \@retval;
+}
+
+sub b_lexinfo_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "lexinfo");
+
+ my $script = $r->location;
+ return qq(\n<a href="$script/$name?noh_b_lexinfo">Lexical Info</a>\n);
+}
+
+sub noh_b_lexinfo {
+ my $r = shift;
+
+ $r->content_type("text/plain");
+ return unless has($r, "lexinfo");
+
+ no strict 'refs';
+ my ($name) = (split "/", $r->uri)[-1];
+ $r->print("Lexical Info for $name\n\n");
+ my $lexi = B::LexInfo->new;
+ my $info = $lexi->cvlexinfo($name);
+ $r->print(${ $lexi->dumper($info) });
+}
+
+my %b_terse_exp = ('slow' => 'syntax', 'exec' => 'execution', basic => 'syntax');
+
+sub b_terse_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "terse");
+
+ my $script = $r->location;
+ my @retval;
+ for (qw(exec basic)) {
+ my $exp = "$b_terse_exp{$_} order";
+ push @retval,
+ qq(\n<a href="$script/$_/$name?noh_b_terse">Syntax Tree Dump ($exp)</a>\n);
+ }
+ join '', @retval;
+}
+
+sub noh_b_terse {
+ my $r = shift;
+
+ $r->content_type("text/plain");
+ return unless has($r, "terse");
+
+ no strict 'refs';
+ my ($arg, $name) = (split "/", $r->uri)[-2,-1];
+ $r->print("Syntax Tree Dump ($b_terse_exp{$arg}) for $name\n\n");
+
+ # XXX: blead perl dumps things to STDERR, though the same version
+ # works fine with 1.27
+ # B::Concise couldn't parse XS code before perl patch 24681 (perl 5.9.3)
+ # B::Terse is deprecated and just a wrapper around B::Concise now adays
+ eval { B::Concise::compile("-terse", "-$arg", $name)->() };
+ if ($@) {
+ $r->print("B::Concise has failed: $@");
+ }
+}
+
+sub b_terse_size_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "tersesize");
+
+ my $script = $r->location;
+ my @retval;
+ for (qw(exec slow)) {
+ my $exp = "$b_terse_exp{$_} order";
+ push @retval,
+ qq(\n<a href="$script/$_/$name?noh_b_terse_size">Syntax Tree Size ($exp)</a>\n);
+ }
+ join '', @retval;
+}
+
+sub noh_b_terse_size {
+ my $r = shift;
+
+ $r->content_type("text/html");
+ return unless has($r, "tersesize");
+
+ $r->print('<pre>');
+ my ($arg, $name) = (split "/", $r->uri)[-2,-1];
+ my $uri = $r->location;
+ my $link = qq{<a href="$uri/$name/CODE?cv_dump">$name</a>};
+ $r->print("Syntax Tree Size ($b_terse_exp{$arg} order) for $link\n\n");
+ B::TerseSize::compile($arg, $name)->();
+}
+
+sub b_package_size_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "packagesize");
+
+ my $script = $r->location;
+ qq(<a href="$script/$name?noh_b_package_size">Memory Usage</a>\n);
+}
+
+sub noh_b_package_size {
+ my ($r) = @_;
+
+ $r->content_type("text/html");
+ return unless has($r, "packagesize");
+
+ $r->print('<pre>');
+
+ no strict 'refs';
+ my ($package) = (split "/", $r->uri)[-1];
+ my $script = $r->location;
+ $r->print("Memory Usage for package $package\n\n");
+ my ($subs, $opcount, $opsize) = B::TerseSize::package_size($package);
+ my $Kb = sprintf "%.2f", $opsize / 1024;
+ my $Mb = sprintf "%.2f", $Kb / 1000;
+ $r->print("Totals: $opsize bytes, $Kb Kb, $Mb Mb | $opcount OPs\n\n");
+
+ my $nlen = 0;
+ my @keys = map {
+ $nlen = length > $nlen ? length : $nlen;
+ $_;
+ } (sort { $subs->{$b}->{size} <=> $subs->{$a}->{size} } keys %$subs);
+
+ my $clen = $subs->{$keys[0]}->{count} ?
+ length $subs->{$keys[0]}->{count} : 0;
+ my $slen = length $subs->{$keys[0]}->{size};
+
+ for my $name (@keys) {
+ my $stats = $subs->{$name};
+ if ($name =~ /^my /) {
+ $r->printf("%-${nlen}s %${slen}d bytes\n", $name, $stats->{size});
+ }
+ elsif ($name =~ /^\*(\w+)\{(\w+)\}/) {
+ my $link = qq(<a href="$script/$package\::$1/$2?data_dump">);
+ $r->printf("$link%-${nlen}s</a> %${slen}d bytes\n",
+ $name, $stats->{size});
+ }
+ else {
+ my $link =
+ qq(<a href="$script/slow/$package\::$name?noh_b_terse_size">);
+ $r->printf("$link%-${nlen}s</a> %${slen}d bytes | %${clen}d OPs\n",
+ $name, $stats->{size}, $stats->{count});
+ }
+ }
+}
+
+sub b_deparse_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "deparse");
+
+ my $script = $r->location;
+ return qq(\n<a href="$script/$name?noh_b_deparse">Deparse</a>\n);
+}
+
+sub noh_b_deparse {
+ my $r = shift;
+
+ $r->content_type("text/plain");
+ return unless has($r, "deparse");
+
+ my $name = (split "/", $r->uri)[-1];
+ $r->print("Deparse of $name\n\n");
+ my $deparse = B::Deparse->new(split /\s+/,
+ $r->dir_config('StatusDeparseOptions')||"");
+ my $body = $deparse->coderef2text(\&{$name});
+ $r->print("sub $name $body");
+}
+
+sub b_fathom_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "fathom");
+
+ my $script = $r->location;
+ return qq(\n<a href="$script/$name?noh_b_fathom">Fathom Score</a>\n);
+}
+
+sub noh_b_fathom {
+ my $r = shift;
+
+ $r->content_type("text/plain");
+ return unless has($r, "fathom");
+
+ my $name = (split "/", $r->uri)[-1];
+ $r->print("Fathom Score of $name\n\n");
+ my $fathom = B::Fathom->new(split /\s+/,
+ $r->dir_config('StatusFathomOptions')||"");
+ $r->print($fathom->fathom(\&{$name}));
+}
+
+sub peek_link {
+ my ($r, $name, $type) = @_;
+
+ return unless has($r, "peek");
+
+ my $script = $r->location;
+ return qq(\n<a href="$script/$name/$type?noh_peek">Peek Dump</a>\n);
+}
+
+sub noh_peek {
+ my $r = shift;
+
+ $r->content_type("text/plain");
+ return unless has($r, "peek");
+
+ no strict 'refs';
+ my ($name, $type) = (split "/", $r->uri)[-2,-1];
+ $type =~ s/^FUNCTION$/CODE/;
+ $r->print("Peek Dump of $name $type\n\n");
+ Apache::Peek::Dump(*{$name}{$type});
+}
+
+sub xref_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "xref");
+
+ my $script = $r->location;
+ return qq(\n<a href="$script/$name?noh_xref">Cross Reference Report</a>\n);
+}
+
+sub noh_xref {
+ my $r = shift;
+
+ $r->content_type("text/plain");
+ return unless has($r, "xref");
+
+ (my $thing = $r->path_info) =~ s:^/::;
+ $r->print("Xref of $thing\n");
+ B::Xref::compile($thing)->();
+}
+
+$Apache2::Status::BGraphCache ||= 0;
+if ($Apache2::Status::BGraphCache) {
+ Apache2->server->push_handlers(PerlChildExitHandler => sub {
+ unlink keys %Apache2::Status::BGraphCache;
+ });
+}
+
+sub b_graph_link {
+ my ($r, $name) = @_;
+
+ return unless has($r, "graph");
+
+ my $script = $r->location;
+ return qq(\n<a href="$script/$name?noh_b_graph">OP Tree Graph</a>\n);
+}
+
+sub noh_b_graph {
+ my $r = shift;
+
+ return unless has($r, "graph");
+
+ untie *STDOUT;
+
+ my $dir = File::Spec->catfile(Apache2::ServerUtil::server_root(),
+ ($r->dir_config("GraphDir") || "logs/b_graphs"));
+
+ mkdir $dir, 0755 unless -d $dir;
+
+ (my $thing = $r->path_info) =~ s:^/::;
+ $thing =~ s{::}{-}g; # :: is not allowed in the filename on some OS
+ my $type = "dot";
+ my $file = "$dir/$thing.$$.gif";
+
+ unless (-e $file) {
+ my $rv = tie *STDOUT, "B::Graph", $r, $file;
+ unless ($rv) {
+ $r->content_type("text/plain");
+ $r->print("dot not found\n");
+ }
+ else {
+ B::Graph::compile("-$type", $thing)->();
+ (tied *STDOUT)->{graph}->close;
+ }
+ }
+
+ if (-s $file) {
+ $r->content_type("image/gif");
+ $r->sendfile($file);
+ }
+ else {
+ $r->content_type("text/plain");
+ $r->print("Graph of $thing failed!\n");
+ }
+ if ($Apache2::Status::BGraphCache) {
+ $Apache2::Status::BGraphCache{$file}++;
+ }
+ else {
+ unlink $file;
+ }
+
+ 0;
+}
+
+sub B::Graph::TIEHANDLE {
+ my ($class, $r, $file) = @_;
+
+ if ($file =~ /^([^<>|;]+)$/) {
+ $file = $1;
+ }
+ else {
+ die "TAINTED data in THING=> ($file)";
+ }
+
+ $ENV{PATH} = join ":", qw{/usr/bin /usr/local/bin};
+ my $dot = $r->dir_config("Dot") || "dot";
+
+ require IO::File;
+ my $pipe = IO::File->new("|$dot -Tgif -o $file");
+ $pipe && $pipe->autoflush(1);
+
+ if ($pipe) {
+ return bless {
+ graph => $pipe,
+ r => $r,
+ }, $class;
+ }
+ else {
+ return;
+ }
+}
+
+sub B::Graph::PRINT {
+ my $self = shift;
+
+ $self->{graph}->print(@_);
+}
+
+my %can_dump = map {$_,1} qw(scalars arrays hashes);
+
+sub as_HTML {
+ my ($self, $package, $r) = @_;
+
+ my @m = qw(<table>);
+ my $uri = $r->location;
+ my $is_main = $package eq "main";
+
+ my $do_dump = has($r, "dumper");
+
+ my @methods = sort keys %{$self->{'AUTOLOAD'}};
+
+ if ($is_main) {
+ @methods = grep { $_ ne "packages" } @methods;
+ unshift @methods, "packages";
+ }
+
+ for my $type (@methods) {
+ (my $dtype = uc $type) =~ s/E?S$//;
+ push @m, "<tr><td valign=\"top\"><b>$type</b></td>";
+ my @line = ();
+
+ for (sort $self->_partdump(uc $type)) {
+ s/([\000-\037\177])/ '^' . pack('c', ord($1) ^ 64)/eg;
+
+ if ($type eq "scalars") {
+ no strict 'refs';
+ next unless defined eval { $$_ };
+ }
+
+ if ($type eq "packages") {
+ push @line, qq(<a href="$uri?$_">$_</a>);
+ }
+ elsif ($type eq "functions") {
+ if (has($r, "b")) {
+ push @line, qq(<a href="$uri/$_/$dtype?cv_dump">$_</a>);
+ }
+ else {
+ push @line, $_;
+ }
+ }
+ elsif ($do_dump and $can_dump{$type}) {
+ next if /_</;
+ push @line, qq(<a href="$uri/$_/$dtype?data_dump">$_</a>);
+ }
+ else {
+ push @line, $_;
+ }
+ }
+ push @m, "<td>" . join(", ", @line) . "</td></tr>\n";
+ }
+ push @m, "</table>";
+
+ return join "\n", @m, "<hr>", b_package_size_link($r, $package);
+}
+
+sub escape_html {
+ my $str = shift;
+
+ $str =~ s/&/&/g;
+ $str =~ s/</</g;
+ $str =~ s/>/>/g;
+
+ return $str;
+}
+
+sub myconfig {
+ require Config;
+ # Config::myconfig(); fails under threads with (5.8.0 < perl < 5.8.3)
+ # "Modification of a read-only value attempted"
+ # provide a workaround
+ if ($Config::Config{useithreads} and $] > 5.008 and $] < 5.008003) {
+ return $Config::summary_expanded if $Config::summary_expanded;
+ ($Config::summary_expanded = $Config::summary) =~
+ s{\$(\w+)}
+ { my $c = $Config::Config{$1}; defined($c) ? $c : 'undef' }ge;
+ return $Config::summary_expanded;
+ }
+ else {
+ return Config::myconfig();
+ }
+}
+
+# mp2 modules have to deal with situations where a binary incompatible
+# mp1 version of the same module is installed in the same
+# tree. therefore when checking for a certain version, one wants to
+# check the version of the module 'require()' will find without
+# loading that module. this function partially adopted from
+# ExtUtils::MM_Unix does just that. it returns the version number of
+# the first module that it finds, forcing numerical context, making
+# the return value suitable for immediate numerical comparison
+# operation. (i.e. 2.03-dev will be returned as 2.03, 0 will be
+# returned when the parsing has failed or a module wasn't found).
+sub parse_version {
+ my $name = shift;
+ die "no module name passed" unless $name;
+ my $file = File::Spec->catfile(split /::/, $name) . '.pm';
+ for my $dir (@INC) {
+ next if ref $dir; # skip code refs
+
+ my $pmfile = File::Spec->catfile($dir, $file);
+ next unless -r $pmfile;
+
+ open my $fh, $pmfile or die "can't open $pmfile: $!";
+
+ my $inpod = 0;
+ my $version;
+ while (<$fh>) {
+ $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
+ next if $inpod || /^\s*#/;
+
+ chomp;
+ next unless /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
+ { local($1, $2); ($_ = $_) = /(.*)/; } # untaint
+ my $eval = qq{
+ package Apache2::Status::_version;
+ no strict;
+
+ local $1$2;
+ \$$2=undef; do {
+ $_
+ }; \$$2
+ };
+ no warnings;
+ $version = eval $eval;
+ warn "Could not eval '$eval' in $pmfile: $@" if $@;
+ last;
+ }
+
+ close $fh;
+
+ # avoid situations like "2.03-dev" and return a numerical
+ # version
+ if (defined $version) {
+ no warnings;
+ $version += 0; # force number
+ return $version;
+ }
+ }
+
+ return 0; # didn't find the file or the version number
+}
+
+1;
+
+__END__
+
diff --git a/2_0_13/lib/Apache2/XSLoader.pm b/2_0_13/lib/Apache2/XSLoader.pm
new file mode 100644
index 0000000..0c848a1
--- /dev/null
+++ b/2_0_13/lib/Apache2/XSLoader.pm
@@ -0,0 +1,37 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::XSLoader;
+
+use strict;
+use warnings FATAL => 'all';
+
+use XSLoader ();
+
+BEGIN {
+ unless (defined &BOOTSTRAP) {
+ *BOOTSTRAP = sub () { 0 };
+ }
+}
+
+sub load {
+ return unless BOOTSTRAP;
+ # do not change the next line and do not insert anything below it in this
+ # function. XSLoader::load depends on it.
+ goto &XSLoader::load;
+}
+
+1;
diff --git a/2_0_13/lib/Apache2/compat.pm b/2_0_13/lib/Apache2/compat.pm
new file mode 100644
index 0000000..2a1a8d7
--- /dev/null
+++ b/2_0_13/lib/Apache2/compat.pm
@@ -0,0 +1,873 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::compat;
+
+use strict;
+use warnings FATAL => 'all';
+no warnings 'redefine';
+
+#1.xx compat layer
+#some of this will stay as-is
+#some will be implemented proper later on
+
+#there's enough here to get simple registry scripts working
+#add to startup.pl:
+#use Apache2::compat ();
+#use lib ...; #or something to find 1.xx Apache2::Registry
+
+#Alias /perl /path/to/perl/scripts
+#<Location /perl>
+# Options +ExecCGI
+# SetHandler modperl
+# PerlResponseHandler Apache2::Registry
+#</Location>
+
+use Apache2::Connection ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Access ();
+use Apache2::Module ();
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use Apache2::Response ();
+use Apache2::SubRequest ();
+use Apache2::Filter ();
+use Apache2::Util ();
+use Apache2::Log ();
+use Apache2::URI ();
+use APR::Date ();
+use APR::Table ();
+use APR::Pool ();
+use APR::URI ();
+use APR::Util ();
+use APR::Brigade ();
+use APR::Bucket ();
+use mod_perl2 ();
+
+use Symbol ();
+use File::Spec ();
+
+use APR::Const -compile => qw(FINFO_NORM FINFO_PROT);
+
+use constant WIN32 => ($^O eq "MSWin32");
+
+BEGIN {
+ $INC{'Apache.pm'} = __FILE__;
+
+ $INC{'Apache/Constants.pm'} = __FILE__;
+
+ $INC{'Apache/File.pm'} = __FILE__;
+
+ $INC{'Apache/Table.pm'} = __FILE__;
+}
+
+($Apache::Server::Starting, $Apache::Server::ReStarting) =
+ Apache2::ServerUtil::restart_count() == 1 ? (1, 0) : (0, 1);
+
+# api => "overriding code"
+# the overriding code, needs to "return" the original CODE reference
+# when eval'ed , so that it can be restored later
+my %overridable_mp2_api = (
+ 'Apache2::RequestRec::filename' => <<'EOI',
+{
+ require Apache2::RequestRec;
+ require APR::Finfo;
+ my $orig_sub = *Apache2::RequestRec::filename{CODE};
+ *Apache2::RequestRec::filename = sub {
+ my ($r, $newfile) = @_;
+ my $old_filename;
+ if (defined $newfile) {
+ $old_filename = $r->$orig_sub($newfile);
+ die "'$newfile' doesn't exist" unless -e $newfile;
+ my $wanted = APR::Const::FINFO_NORM;
+ if (WIN32) {
+ $wanted &= ~APR::Const::FINFO_PROT;
+ }
+ $r->finfo(APR::Finfo::stat($newfile, $wanted, $r->pool));
+ }
+ else {
+ $old_filename = $r->$orig_sub();
+ }
+ return $old_filename;
+ };
+ $orig_sub;
+}
+
+EOI
+ 'Apache2::RequestRec::notes' => <<'EOI',
+{
+ require Apache2::RequestRec;
+ my $orig_sub = *Apache2::RequestRec::notes{CODE};
+ *Apache2::RequestRec::notes = sub {
+ my $r = shift;
+ return wantarray()
+ ? ($r->table_get_set(scalar($r->$orig_sub), @_))
+ : scalar($r->table_get_set(scalar($r->$orig_sub), @_));
+ };
+ $orig_sub;
+}
+EOI
+
+ 'Apache2::RequestRec::finfo' => <<'EOI',
+{
+ require APR::Finfo;
+ my $orig_sub = *APR::Finfo::finfo{CODE};
+ sub Apache2::RequestRec::finfo {
+ my $r = shift;
+ stat $r->filename;
+ \*_;
+ }
+ $orig_sub;
+}
+EOI
+
+ 'Apache2::Connection::local_addr' => <<'EOI',
+{
+ require Apache2::Connection;
+ require Socket;
+ require APR::SockAddr;
+ my $orig_sub = *Apache2::Connection::local_addr{CODE};
+ *Apache2::Connection::local_addr = sub {
+ my $c = shift;
+ Socket::pack_sockaddr_in($c->$orig_sub->port,
+ Socket::inet_aton($c->$orig_sub->ip_get));
+ };
+ $orig_sub;
+}
+EOI
+
+ 'Apache2::Connection::remote_addr' => <<'EOI',
+{
+ require Apache2::Connection;
+ require APR::SockAddr;
+ require Socket;
+ my $orig_sub;
+ if (defined *Apache2::Connection::client_addr{CODE}) { # httpd-2.4
+ $orig_sub = *Apache2::Connection::client_addr{CODE};
+ } else { # httpd-2.2
+ $orig_sub = *Apache2::Connection::remote_addr{CODE};
+ }
+ *Apache2::Connection::remote_addr = sub {
+ my $c = shift;
+ if (@_) {
+ my $addr_in = shift;
+ my ($port, $addr) = Socket::unpack_sockaddr_in($addr_in);
+ $c->$orig_sub->ip_set($addr);
+ $c->$orig_sub->port_set($port);
+ }
+ else {
+ Socket::pack_sockaddr_in($c->$orig_sub->port,
+ Socket::inet_aton($c->$orig_sub->ip_get));
+ }
+ };
+ $orig_sub;
+}
+EOI
+
+ 'Apache2::Module::top_module' => <<'EOI',
+{
+ require Apache2::Module;
+ my $orig_sub = *Apache2::Module::top_module{CODE};
+ *Apache2::Module::top_module = sub {
+ shift;
+ $orig_sub->(@_);
+ };
+ $orig_sub;
+}
+EOI
+
+ 'Apache2::Module::get_config' => <<'EOI',
+{
+ require Apache2::Module;
+ my $orig_sub = *Apache2::Module::get_config{CODE};
+ *Apache2::Module::get_config = sub {
+ shift;
+ $orig_sub->(@_);
+ };
+ $orig_sub;
+}
+EOI
+
+ 'APR::URI::unparse' => <<'EOI',
+{
+ require APR::URI;
+ my $orig_sub = *APR::URI::unparse{CODE};
+ *APR::URI::unparse = sub {
+ my ($uri, $flags) = @_;
+
+ if (defined $uri->hostname && !defined $uri->scheme) {
+ # we do this only for back compat, the new APR::URI is
+ # protocol-agnostic and doesn't fallback to 'http' when the
+ # scheme is not provided
+ $uri->scheme('http');
+ }
+
+ $orig_sub->(@_);
+ };
+ $orig_sub;
+}
+EOI
+
+ 'Apache2::Util::ht_time' => <<'EOI',
+{
+ require Apache2::Util;
+ my $orig_sub = *Apache2::Util::ht_time{CODE};
+ *Apache2::Util::ht_time = sub {
+ my $r = Apache2::compat::request('Apache2::Util::ht_time');
+ return $orig_sub->($r->pool, @_);
+ };
+ $orig_sub;
+}
+
+EOI
+
+);
+
+my %overridden_mp2_api = ();
+
+# this function enables back-compatible APIs which can't coexist with
+# mod_perl 2.0 APIs with the same name and therefore it should be
+# avoided if possible.
+#
+# it expects a list of fully qualified functions, like
+# "Apache2::RequestRec::finfo"
+sub override_mp2_api {
+ my (@subs) = @_;
+
+ for my $sub (@subs) {
+ unless (exists $overridable_mp2_api{$sub}) {
+ die __PACKAGE__ . ": $sub is not overridable";
+ }
+ if (exists $overridden_mp2_api{$sub}) {
+ warn __PACKAGE__ . ": $sub has been already overridden";
+ next;
+ }
+ $overridden_mp2_api{$sub} = eval $overridable_mp2_api{$sub};
+ if ($@) {
+ die "error overriding $sub : $@";
+ }
+ unless (exists $overridden_mp2_api{$sub} &&
+ ref($overridden_mp2_api{$sub}) eq 'CODE') {
+ die "overriding $sub didn't return a CODE ref";
+ }
+ }
+}
+
+# restore_mp2_api does the opposite of override_mp2_api(), it removes
+# the overriden API and restores the original mod_perl 2.0 API
+sub restore_mp2_api {
+ my (@subs) = @_;
+
+ for my $sub (@subs) {
+ unless (exists $overridable_mp2_api{$sub}) {
+ die __PACKAGE__ . ": $sub is not overridable";
+ }
+ unless (exists $overridden_mp2_api{$sub}) {
+ warn __PACKAGE__ . ": can't restore $sub, " .
+ "as it has not been overridden";
+ next;
+ }
+ # XXX: 5.8.2+ can't delete and assign at once - gives:
+ # Attempt to free unreferenced scalar
+ # after perl_clone. the 2 step works ok. to reproduce:
+ # t/TEST -maxclients 1 perl/ithreads2.t compat/request.t
+ my $original_sub = $overridden_mp2_api{$sub};
+ delete $overridden_mp2_api{$sub};
+ no warnings 'redefine';
+ no strict 'refs';
+ *$sub = $original_sub;
+ }
+}
+
+sub request {
+ my $what = shift;
+
+ my $r = Apache2::RequestUtil->request;
+
+ unless ($r) {
+ die "cannot use $what ",
+ "without 'SetHandler perl-script' ",
+ "or 'PerlOptions +GlobalRequest'";
+ }
+
+ $r;
+}
+
+{
+ my $orig_sub = *Apache2::Module::top_module{CODE};
+ *Apache2::Module::top_module = sub {
+ $orig_sub->();
+ };
+}
+
+{
+ my $orig_sub = *Apache2::Module::get_config{CODE};
+ *Apache2::Module::get_config = sub {
+ shift if $_[0] eq 'Apache2::Module';
+ $orig_sub->(@_);
+ };
+}
+
+package Apache::Server;
+# XXX: is that good enough? see modperl/src/modules/perl/mod_perl.c:367
+our $CWD = Apache2::ServerUtil::server_root();
+
+our $AddPerlVersion = 1;
+
+sub warn {
+ shift if @_ and $_[0] eq 'Apache::Server';
+ Apache2::ServerRec::warn(@_);
+}
+
+package Apache;
+
+sub request {
+ return Apache2::compat::request(@_);
+}
+
+sub unescape_url_info {
+ my ($class, $string) = @_;
+ Apache2::URI::unescape_url($string);
+ $string =~ tr/+/ /;
+ $string;
+}
+
+#sorry, have to use $r->Apache2::args at the moment
+#for list context splitting
+
+sub args {
+ my $r = shift;
+ my $args = $r->args;
+ return $args unless wantarray;
+ return $r->parse_args($args);
+}
+
+sub server_root_relative {
+ my $class = shift;
+ if (@_ && defined($_[0]) && File::Spec->file_name_is_absolute($_[0])) {
+ return File::Spec->catfile(@_);
+ }
+ else {
+ File::Spec->catfile(Apache2::ServerUtil::server_root(), @_);
+ }
+}
+
+sub exit {
+ require ModPerl::Util;
+
+ my $status = 0;
+ my $nargs = @_;
+
+ if ($nargs == 2) {
+ $status = $_[1];
+ }
+ elsif ($nargs == 1 and $_[0] =~ /^\d+$/) {
+ $status = $_[0];
+ }
+
+ ModPerl::Util::exit($status);
+}
+
+#XXX: warn
+sub import {
+}
+
+sub untaint {
+ shift;
+ require ModPerl::Util;
+ ModPerl::Util::untaint(@_);
+}
+
+sub module {
+ require Apache2::Module;
+ die 'Usage: Apache2->module($name)' if @_ != 2;
+ return Apache2::Module::loaded($_[1]);
+}
+
+sub gensym {
+ return Symbol::gensym();
+}
+
+sub define {
+ shift if @_ == 2;
+ Apache2::ServerUtil::exists_config_define(@_);
+}
+
+sub log_error {
+ Apache2::ServerUtil->server->log_error(@_);
+}
+
+sub warn {
+ shift if @_ and $_[0] eq 'Apache';
+ Apache2::ServerRec::warn(@_);
+}
+
+sub httpd_conf {
+ shift;
+ my $obj;
+ eval { $obj = Apache2::RequestUtil->request };
+ $obj = Apache2::ServerUtil->server if $@;
+ my $err = $obj->add_config([split /\n/, join '', @_]);
+ die $err if $err;
+}
+
+# mp2 always can stack handlers
+sub can_stack_handlers { 1; }
+
+sub push_handlers {
+ shift;
+ Apache2::ServerUtil->server->push_handlers(@_);
+}
+
+sub set_handlers {
+ shift;
+ Apache2::ServerUtil->server->set_handlers(@_);
+}
+
+sub get_handlers {
+ shift;
+ Apache2::ServerUtil->server->get_handlers(@_);
+}
+
+package Apache::Constants;
+
+use Apache2::Const ();
+
+sub import {
+ my $class = shift;
+ my $package = scalar caller;
+
+ my @args = @_;
+
+ # treat :response as :common - it's not perfect
+ # but simple and close enough for the majority
+ my %args = map { s/^:response$/:common/; $_ => 1 } @args;
+
+ Apache2::Const->compile($package => keys %args);
+}
+
+#no need to support in 2.0
+sub export {}
+
+sub SERVER_VERSION { Apache2::ServerUtil::get_server_version() }
+
+package Apache2::RequestRec;
+
+use Apache2::Const -compile => qw(REMOTE_NAME);
+
+#no longer exist in 2.0
+sub soft_timeout {}
+sub hard_timeout {}
+sub kill_timeout {}
+sub reset_timeout {}
+
+# this function is from mp1's Apache2::SubProcess 3rd party module
+# which is now a part of mp2 API. this function doesn't exist in 2.0.
+sub cleanup_for_exec {}
+
+sub current_callback {
+ require ModPerl::Util;
+ return ModPerl::Util::current_callback();
+}
+
+sub send_http_header {
+ my ($r, $type) = @_;
+
+ # since send_http_header() in mp1 was telling mod_perl not to
+ # parse headers and in mp2 one must call $r->content_type($type) to
+ # perform the same, we make sure that this happens
+ $type = $r->content_type || 'text/html' unless defined $type;
+
+ $r->content_type($type);
+}
+
+#we support Apache2::RequestUtil->request; this is needed to support $r->request
+#XXX: seems sorta backwards
+*request = \&Apache2::request;
+
+sub table_get_set {
+ my ($r, $table) = (shift, shift);
+ my ($key, $value) = @_;
+
+ if (1 == @_) {
+ return wantarray()
+ ? ($table->get($key))
+ : scalar($table->get($key));
+ }
+ elsif (2 == @_) {
+ if (defined $value) {
+ return wantarray()
+ ? ($table->set($key, $value))
+ : scalar($table->set($key, $value));
+ }
+ else {
+ return wantarray()
+ ? ($table->unset($key))
+ : scalar($table->unset($key));
+ }
+ }
+ elsif (0 == @_) {
+ return $table;
+ }
+ else {
+ my $name = (caller(1))[3];
+ $r->warn("Usage: \$r->$name([key [,val]])");
+ }
+}
+
+sub header_out {
+ my $r = shift;
+ return wantarray()
+ ? ($r->table_get_set(scalar($r->headers_out), @_))
+ : scalar($r->table_get_set(scalar($r->headers_out), @_));
+}
+
+sub header_in {
+ my $r = shift;
+ return wantarray()
+ ? ($r->table_get_set(scalar($r->headers_in), @_))
+ : scalar($r->table_get_set(scalar($r->headers_in), @_));
+}
+
+sub err_header_out {
+ my $r = shift;
+ return wantarray()
+ ? ($r->table_get_set(scalar($r->err_headers_out), @_))
+ : scalar($r->table_get_set(scalar($r->err_headers_out), @_));
+}
+
+
+sub register_cleanup {
+ shift->pool->cleanup_register(@_);
+}
+
+*post_connection = \®ister_cleanup;
+
+sub get_remote_host {
+ my ($r, $type) = @_;
+ $type = Apache2::Const::REMOTE_NAME unless defined $type;
+ $r->connection->get_remote_host($type, $r->per_dir_config);
+}
+
+sub parse_args {
+ my ($r, $string) = @_;
+ return () unless defined $string and $string;
+
+ return map {
+ tr/+/ /;
+ s/%([0-9a-fA-F]{2})/pack("C",hex($1))/ge;
+ $_;
+ } split /[=&;]/, $string, -1;
+}
+
+use Apache2::Const -compile => qw(MODE_READBYTES);
+use APR::Const -compile => qw(SUCCESS BLOCK_READ);
+
+use constant IOBUFSIZE => 8192;
+
+sub content {
+ my $r = shift;
+
+ my $bb = APR::Brigade->new($r->pool,
+ $r->connection->bucket_alloc);
+
+ my $data = '';
+ my $seen_eos = 0;
+ do {
+ $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
+ APR::Const::BLOCK_READ, IOBUFSIZE);
+ while (!$bb->is_empty) {
+ my $b = $bb->first;
+
+ if ($b->is_eos) {
+ $seen_eos++;
+ last;
+ }
+
+ if ($b->read(my $buf)) {
+ $data .= $buf;
+ }
+
+ $b->delete;
+ }
+ } while (!$seen_eos);
+
+ $bb->destroy;
+
+ return $data unless wantarray;
+ return $r->parse_args($data);
+}
+
+sub server_root_relative {
+ my $r = shift;
+ File::Spec->catfile(Apache2::ServerUtil::server_root(), @_);
+}
+
+sub clear_rgy_endav {
+ my ($r, $script_name) = @_;
+ require ModPerl::Global;
+ my $package = 'Apache2::ROOT' . $script_name;
+ ModPerl::Global::special_list_clear(END => $package);
+}
+
+sub stash_rgy_endav {
+ #see run_rgy_endav
+}
+
+#if somebody really wants to have END subroutine support
+#with the 1.x Apache2::Registry they will need to configure:
+# PerlHandler Apache2::Registry Apache2::compat::run_rgy_endav
+sub Apache2::compat::run_rgy_endav {
+ my $r = shift;
+
+ require ModPerl::Global;
+ require Apache2::PerlRun; #1.x's
+ my $package = Apache2::PerlRun->new($r)->namespace;
+
+ ModPerl::Global::special_list_call(END => $package);
+}
+
+sub seqno {
+ 1;
+}
+
+sub chdir_file {
+ #XXX resolve '.' in @INC to basename $r->filename
+}
+
+#XXX: would like to have a proper implementation
+#that reads line-by-line as defined by $/
+#the best way will probably be to use perlio in 5.8.0
+#anything else would be more effort than it is worth
+sub READLINE {
+ my $r = shift;
+ my $line;
+ $r->read($line, $r->headers_in->get('Content-length'));
+ $line ? $line : undef;
+}
+
+#XXX: howto convert PerlIO to apr_file_t
+#so we can use the real ap_send_fd function
+#2.0 ap_send_fd() also has an additional offset parameter
+
+sub send_fd_length {
+ my ($r, $fh, $length) = @_;
+
+ my $buff;
+ my $total_bytes_sent = 0;
+ my $len;
+
+ return 0 if $length == 0;
+
+ if (($length > 0) && ($total_bytes_sent + IOBUFSIZE) > $length) {
+ $len = $length - $total_bytes_sent;
+ }
+ else {
+ $len = IOBUFSIZE;
+ }
+
+ binmode $fh;
+
+ while (CORE::read($fh, $buff, $len)) {
+ $total_bytes_sent += $r->puts($buff);
+ }
+
+ $total_bytes_sent;
+}
+
+sub send_fd {
+ my ($r, $fh) = @_;
+ $r->send_fd_length($fh, -1);
+}
+
+sub is_main { !shift->main }
+
+# really old back-compat methods, they shouldn't be used in mp1
+*cgi_var = *cgi_env = \&Apache2::RequestRec::subprocess_env;
+
+package Apache::File;
+
+use Fcntl ();
+use Symbol ();
+use Carp ();
+
+sub new {
+ my ($class) = shift;
+ my $fh = Symbol::gensym;
+ my $self = bless $fh, ref($class)||$class;
+ if (@_) {
+ return $self->open(@_) ? $self : undef;
+ }
+ else {
+ return $self;
+ }
+}
+
+sub open {
+ my ($self) = shift;
+
+ Carp::croak("no Apache2::File object passed")
+ unless $self && ref($self);
+
+ # cannot forward @_ to open() because of its prototype
+ if (@_ > 1) {
+ my ($mode, $file) = @_;
+ CORE::open $self, $mode, $file;
+ }
+ else {
+ my $file = shift;
+ CORE::open $self, $file;
+ }
+}
+
+sub close {
+ my ($self) = shift;
+ CORE::close $self;
+}
+
+my $TMPNAM = 'aaaaaa';
+my $TMPDIR = $ENV{'TMPDIR'} || $ENV{'TEMP'} || '/tmp';
+($TMPDIR) = $TMPDIR =~ /^([^<>|;*]+)$/; #untaint
+my $Mode = Fcntl::O_RDWR()|Fcntl::O_EXCL()|Fcntl::O_CREAT();
+my $Perms = 0600;
+
+sub tmpfile {
+ my $class = shift;
+ my $limit = 100;
+ my $r = Apache2::compat::request('Apache::File->tmpfile');
+
+ while ($limit--) {
+ my $tmpfile = "$TMPDIR/${$}" . $TMPNAM++;
+ my $fh = $class->new;
+
+ sysopen $fh, $tmpfile, $Mode, $Perms
+ or die "failed to open $tmpfile: $!";
+ $r->pool->cleanup_register(sub { unlink $tmpfile });
+
+ if ($fh) {
+ return wantarray ? ($tmpfile, $fh) : $fh;
+ }
+ }
+}
+
+# the following functions now live in Apache2::RequestIO
+# * discard_request_body
+
+# the following functions now live in Apache2::Response
+# * meets_conditions
+# * set_content_length
+# * set_etag
+# * set_last_modified
+# * update_mtime
+
+# the following functions now live in Apache2::RequestRec
+# * mtime
+
+package Apache::Util;
+
+sub size_string {
+ my ($size) = @_;
+
+ if (!$size) {
+ $size = " 0k";
+ }
+ elsif ($size == -1) {
+ $size = " -";
+ }
+ elsif ($size < 1024) {
+ $size = " 1k";
+ }
+ elsif ($size < 1048576) {
+ $size = sprintf "%4dk", ($size + 512) / 1024;
+ }
+ elsif ($size < 103809024) {
+ $size = sprintf "%4.1fM", $size / 1048576.0;
+ }
+ else {
+ $size = sprintf "%4dM", ($size + 524288) / 1048576;
+ }
+
+ return $size;
+}
+
+*unescape_uri = \&Apache2::URI::unescape_url;
+
+*escape_path = \&Apache2::Util::escape_path;
+
+sub escape_uri {
+ my $path = shift;
+ my $r = Apache2::compat::request('Apache2::Util::escape_uri');
+ Apache2::Util::escape_path($path, $r->pool);
+}
+
+#tmp compat until ap_escape_html is reworked to not require a pool
+my %html_escapes = (
+ '<' => 'lt',
+ '>' => 'gt',
+ '&' => 'amp',
+ '"' => 'quot',
+);
+
+%html_escapes = map { $_, "&$html_escapes{$_};" } keys %html_escapes;
+
+my $html_escape = join '|', keys %html_escapes;
+
+sub escape_html {
+ my $html = shift;
+ $html =~ s/($html_escape)/$html_escapes{$1}/go;
+ $html;
+}
+
+*parsedate = \&APR::Date::parse_http;
+
+*validate_password = \&APR::Util::password_validate;
+
+sub Apache2::URI::parse {
+ my ($class, $r, $uri) = @_;
+
+ $uri ||= $r->construct_url;
+
+ APR::URI->parse($r->pool, $uri);
+}
+
+package Apache::Table;
+
+sub new {
+ my ($class, $r, $nelts) = @_;
+ $nelts ||= 10;
+ APR::Table::make($r->pool, $nelts);
+}
+
+package Apache::SIG;
+
+use Apache2::Const -compile => 'DECLINED';
+
+sub handler {
+ # don't set the SIGPIPE
+ return Apache2::Const::DECLINED;
+}
+
+package Apache2::Connection;
+
+# auth_type and user records don't exist in 2.0 conn_rec struct
+# 'PerlOptions +GlobalRequest' is required
+sub auth_type { shift; Apache2::RequestUtil->request->ap_auth_type(@_) }
+sub user { shift; Apache2::RequestUtil->request->user(@_) }
+
+1;
+__END__
diff --git a/2_0_13/lib/Apache2/porting.pm b/2_0_13/lib/Apache2/porting.pm
new file mode 100644
index 0000000..2432604
--- /dev/null
+++ b/2_0_13/lib/Apache2/porting.pm
@@ -0,0 +1,105 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::porting;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Carp 'croak';
+
+use ModPerl::MethodLookup ();
+use Apache2::ServerUtil;
+
+use Apache2::Const -compile => 'OK';
+
+our $AUTOLOAD;
+
+### methods ###
+# handle:
+# - removed and replaced methods
+# - hinting the package names in which methods reside
+
+my %avail_methods = map { $_ => 1 }
+ (ModPerl::MethodLookup::avail_methods(),
+ ModPerl::MethodLookup::avail_methods_compat());
+
+# XXX: unfortunately it doesn't seem to be possible to install
+# *UNIVERSAL::AUTOLOAD at the server startup, httpd segfaults,
+# child_init seems to be the first stage where it works.
+Apache2::ServerUtil->server->push_handlers(
+ PerlChildInitHandler => \&porting_autoload);
+
+sub porting_autoload {
+ *UNIVERSAL::AUTOLOAD = sub {
+ # This is a porting module, no compatibility layers are allowed in
+ # this zone
+ croak("Apache2::porting can't be used with Apache2::compat")
+ if exists $ENV{"Apache2/compat.pm"};
+
+ (my $method = $AUTOLOAD) =~ s/.*:://;
+
+ # we skip DESTROY methods
+ return if $method eq 'DESTROY';
+
+ # we don't handle methods that we don't know about
+ croak "Undefined subroutine $AUTOLOAD called"
+ unless defined $method && exists $avail_methods{$method};
+
+ my ($hint, @modules) =
+ ModPerl::MethodLookup::lookup_method($method, @_);
+ $hint ||= "Can't find method $AUTOLOAD";
+ croak $hint;
+ };
+
+ return Apache2::Const::OK;
+}
+
+### packages ###
+# handle:
+# - removed and replaced packages
+
+my %packages = (
+ 'Apache::Constants' => [qw(Apache2::Const)],
+ 'Apache::Table' => [qw(APR::Table)],
+ 'Apache::File' => [qw(Apache2::Response Apache2::RequestRec)],
+ 'Apache' => [qw(ModPerl::Util Apache2::Module)],
+);
+
+BEGIN {
+ sub my_require {
+ my $package = $_[0];
+ $package =~ s|/|::|g;
+ $package =~ s|.pm$||;
+
+ # this picks the original require (which could be overriden
+ # elsewhere, so we don't lose that) because we haven't
+ # overriden it yet
+ return require $_[0] unless $packages{$package};
+
+ my $msg = "mod_perl 2.0 API doesn't include package '$package'.";
+ my @replacements = @{ $packages{$package}||[] };
+ if (@replacements) {
+ $msg .= " The package '$package' has moved to " .
+ join " ", map qq/'$_'/, @replacements;
+ }
+ croak $msg;
+ };
+
+ *CORE::GLOBAL::require = sub (*) { my_require($_[0])};
+}
+
+1;
diff --git a/2_0_13/lib/Bundle/Apache2.pm b/2_0_13/lib/Bundle/Apache2.pm
new file mode 100644
index 0000000..7b9ec42
--- /dev/null
+++ b/2_0_13/lib/Bundle/Apache2.pm
@@ -0,0 +1,70 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Bundle::Apache2;
+
+$VERSION = '1.00';
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bundle::Apache2 - Install Apache mod_perl2 and related modules
+
+
+
+=head1 SYNOPSIS
+
+C<perl -MCPAN -e 'install Bundle::Apache2'>
+
+
+
+=head1 CONTENTS
+
+Bundle::ApacheTest - Needs for testing
+
+CGI 3.11 - Used in testing (it's in core, but some vendors exclude it)
+
+Chatbot::Eliza - Used in testing
+
+Compress::Zlib - Used in testing
+
+Devel::Symdump - Symbol table browsing with Apache::Status
+
+HTML::HeadParser - Used in testing
+
+IPC::Run3 - Used in testing
+
+LWP - Used in testing
+
+
+
+
+=head1 DESCRIPTION
+
+This bundle contains modules used by Apache mod_perl2.
+
+Asking CPAN.pm to install a bundle means to install the bundle itself
+along with all the modules contained in the CONTENTS section
+above. Modules that are up to date are not installed, of course.
+
+
+
+=head1 AUTHOR
+
+mod_perl 2 development team
diff --git a/2_0_13/lib/ModPerl/BuildMM.pm b/2_0_13/lib/ModPerl/BuildMM.pm
new file mode 100644
index 0000000..849f35e
--- /dev/null
+++ b/2_0_13/lib/ModPerl/BuildMM.pm
@@ -0,0 +1,377 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::BuildMM;
+
+use strict;
+use warnings;
+
+use ExtUtils::MakeMaker ();
+use Cwd ();
+use File::Spec::Functions qw(catdir catfile splitdir);
+use File::Basename;
+use File::Find;
+
+use Apache2::Build ();
+use ModPerl::MM;
+use constant WIN32 => Apache2::Build::WIN32;
+use constant CYGWIN => Apache2::Build::CYGWIN;
+
+our %PM; #add files to installation
+
+# MM methods that this package overrides
+no strict 'refs';
+my $stash = \%{__PACKAGE__ . '::MY::'};
+my @methods = grep *{$stash->{$_}}{CODE}, keys %$stash;
+ModPerl::MM::override_eu_mm_mv_all_methods(@methods);
+use strict 'refs';
+
+my $apache_test_dir = catdir Cwd::getcwd(), "Apache-Test", "lib";
+
+#to override MakeMaker MOD_INSTALL macro
+sub mod_install {
+ q{$(PERL) -I$(INST_LIB) -I$(PERL_LIB) \\}."\n" .
+ qq{-I$apache_test_dir -MModPerl::BuildMM \\}."\n" .
+ q{-e "ExtUtils::Install::install({@ARGV},'$(VERBINST)',0,'$(UNINST)');"}."\n";
+}
+
+my $build;
+
+sub build_config {
+ my $key = shift;
+ $build ||= Apache2::Build->build_config;
+ return $build unless $key;
+ $build->{$key};
+}
+
+#the parent WriteMakefile moves MY:: methods into a different class
+#so alias them each time WriteMakefile is called in a subdir
+
+sub my_import {
+ no strict 'refs';
+ my $stash = \%{__PACKAGE__ . '::MY::'};
+ for my $sym (keys %$stash) {
+ next unless *{$stash->{$sym}}{CODE};
+ my $name = "MY::$sym";
+ undef &$name if defined &$name;
+ *$name = *{$stash->{$sym}}{CODE};
+ }
+}
+
+sub WriteMakefile {
+ my %args = @_;
+
+ $build ||= build_config();
+ ModPerl::MM::my_import(__PACKAGE__);
+
+ my $inc = $args{INC} || '';
+ $inc = $args{INC} if $args{INC};
+ $inc .= " " . $build->inc;
+ if (my $glue_inc = $build->{MP_XS_GLUE_DIR}) {
+ for (split /\s+/, $glue_inc) {
+ $inc .= " -I$_";
+ }
+ }
+
+ my $libs;
+ my @libs = ();
+ push @libs, $args{LIBS} if $args{LIBS};
+ if (Apache2::Build::BUILD_APREXT) {
+ # in order to decouple APR/APR::* from mod_perl.so,
+ # link these modules against the static MP_APR_LIB lib,
+ # rather than the mod_perl lib (which would demand mod_perl.so
+ # be available). For other modules, use mod_perl.lib as
+ # usual. This is done for APR in xs/APR/APR/Makefile.PL.
+ my $name = $args{NAME};
+ if ($name =~ /^APR::\w+$/) {
+ # For cygwin compatibility, the order of the libs should be
+ # <mod_perl libs> <apache libs>
+ @libs = ($build->mp_apr_lib, $build->apache_libs);
+ }
+ else {
+ @libs = ($build->modperl_libs, $build->apache_libs);
+ }
+ }
+ else {
+ @libs = ($build->modperl_libs, $build->apache_libs);
+ }
+ $libs = join ' ', @libs;
+
+ my $ccflags;
+ $ccflags = $args{CCFLAGS} if $args{CCFLAGS};
+ $ccflags = " " . $build->perl_ccopts . $build->ap_ccopts;
+
+ my $optimize;
+ $optimize = $args{OPTIMIZE} if $args{OPTIMIZE};
+ $optimize = " " . $build->perl_config('optimize');
+
+ my $lddlflags;
+ $lddlflags = $args{LDDLFLAGS} if $args{LDDLFLAGS};
+ $lddlflags = " " . $build->perl_config('lddlflags');
+
+ my %dynamic_lib;
+ %dynamic_lib = %{ $args{dynamic_lib}||{} } if $args{dynamic_lib};
+ $dynamic_lib{OTHERLDFLAGS} = $build->otherldflags;
+
+ my @opts = (
+ INC => $inc,
+ CCFLAGS => $ccflags,
+ OPTIMIZE => $optimize,
+ LDDLFLAGS => $lddlflags,
+ LIBS => $libs,
+ dynamic_lib => \%dynamic_lib,
+ );
+
+ my @typemaps;
+ push @typemaps, $args{TYPEMAPS} if $args{TYPEMAPS};
+ my $pwd = Cwd::fastcwd();
+ for ('xs', $pwd, "$pwd/..") {
+ my $typemap = $build->file_path("$_/typemap");
+ if (-e $typemap) {
+ push @typemaps, $typemap;
+ }
+ }
+ push @opts, TYPEMAPS => \@typemaps if @typemaps;
+
+ my $clean_files = (exists $args{clean} && exists $args{clean}{FILES}) ?
+ $args{clean}{FILES} : '';
+ $clean_files .= " glue_pods"; # cleanup the dependency target
+ $args{clean}{FILES} = $clean_files;
+
+ ExtUtils::MakeMaker::WriteMakefile(@opts, %args);
+}
+
+my %always_dynamic = map { $_, 1 }
+ qw(ModPerl::Const Apache2::Const APR::Const APR APR::PerlIO);
+
+sub ModPerl::BuildMM::MY::constants {
+ my $self = shift;
+ $build ||= build_config();
+
+ #"discover" xs modules. since there is no list hardwired
+ #any module can be unpacked in the mod_perl-2.xx directory
+ #and built static
+
+ #this stunt also make it possible to leave .xs files where
+ #they are, unlike 1.xx where *.xs live in src/modules/perl
+ #and are copied to subdir/ if DYNAMIC=1
+
+ if ($build->{MP_STATIC_EXTS}) {
+ #skip .xs -> .so if we are linking static
+ my $name = $self->{NAME};
+ unless ($always_dynamic{$name}) {
+ if (my ($xs) = keys %{ $self->{XS} }) {
+ $self->{HAS_LINK_CODE} = 0;
+ print "$name will be linked static\n";
+ #propagate static xs module to src/modules/perl/Makefile
+ $build->{XS}->{$name} =
+ join '/', Cwd::fastcwd(), $xs;
+ $build->save;
+ }
+ }
+ }
+
+ $self->MM::constants;
+}
+
+sub ModPerl::BuildMM::MY::top_targets {
+ my $self = shift;
+ my $string = $self->MM::top_targets;
+
+ return $string;
+}
+
+sub ModPerl::BuildMM::MY::postamble {
+ my $self = shift;
+
+ my $doc_root = catdir Cwd::getcwd(), "docs", "api";
+
+ my @targets = ();
+
+ # reasons for glueing pods to the respective .pm files:
+ # - manpages will get installed over the mp1 manpages and vice
+ # versa. glueing pods avoids creation of manpages, but may be we
+ # could just tell make to skip manpages creation?
+ # if pods are installed directly they need to be also redirected,
+ # some into Apache2/ others (e.g. Apache2) not
+
+ # add the code to glue the existing pods to the .pm files in blib.
+ # create a dependency on pm_to_blib subdirs linkext targets to
+ # allow 'make -j'
+ require ExtUtils::MakeMaker;
+ my $mm_ver = $ExtUtils::MakeMaker::VERSION;
+ $mm_ver =~ s/_.*//; # handle dev versions like 6.30_01
+ my $pm_to_blib = ($mm_ver >= 6.22 && $mm_ver <= 6.25)
+ ? "pm_to_blib.ts"
+ : "pm_to_blib";
+ my @target = ("glue_pods: $pm_to_blib subdirs linkext");
+
+ if (-d $doc_root) {
+ my $build = build_config();
+
+ # those living in modperl-2.0/lib are already nicely mapped
+ my %pms = %{ $self->{PM} };
+
+ my $cwd = Cwd::getcwd();
+ my $blib_dir = catdir qw(blib lib);
+
+ # those autogenerated under WrapXS/
+ # those living under xs/
+ # those living under ModPerl-Registry/lib/
+ my @src = ('WrapXS', 'xs', catdir(qw(ModPerl-Registry lib)));
+
+ for my $base (@src) {
+ chdir $base;
+ my @files = ();
+ find({ no_chdir => 1,
+ wanted => sub { push @files, $_ if /.pm$/ },
+ }, ".");
+ chdir $cwd;
+
+ for (@files) {
+ my $pm = catfile $base, $_;
+ my $blib;
+ if ($base =~ /^(xs|WrapXS)/) {
+ my @segm = splitdir $_;
+ splice @segm, -2, 1; # xs/APR/Const/Const.pm
+ splice @segm, -2, 1 if /APR.pm/; # odd case
+ $blib = catfile $blib_dir, @segm;
+ }
+ else {
+ $blib = catfile $blib_dir, $_;
+ }
+ $pms{$pm} = $blib;
+ }
+ }
+
+ foreach my $pm (sort keys %pms) {
+ my $blib = $pms{$pm};
+ $pm =~ s|/\./|/|g; # clean the path
+ $blib =~ s|/\./|/|g; # clean the path
+ my @segm = splitdir $blib;
+ for my $i (1..2) {
+ # try APR.pm and APR/Bucket.pm
+ my $pod = catdir(@segm[-$i .. -1]);
+ $pod =~ s/\.pm/\.pod/;
+ my $podpath = catfile $doc_root, $pod;
+ next unless -r $podpath;
+
+ push @target,
+ '$(FULLPERL) -I$(INST_LIB) ' .
+ "-I$apache_test_dir -MModPerl::BuildMM " .
+ "-e ModPerl::BuildMM::glue_pod $pm $podpath $blib";
+
+ # Win32 doesn't normally install man pages
+ # and Cygwin doesn't allow '::' in file names
+ next if WIN32 || CYGWIN;
+
+ # manify while we're at it
+ my (undef, $man, undef) = $blib =~ m!(blib/lib/)(.*)(\.pm)!;
+ $man =~ s!/!::!g;
+
+ push @target,
+ '$(NOECHO) $(POD2MAN_EXE) --section=3 ' .
+ "$podpath \$(INST_MAN3DIR)/$man.\$(MAN3EXT)"
+ }
+ }
+
+ push @target, $self->{NOECHO} . '$(TOUCH) $@';
+ }
+ else {
+ # we don't have the docs sub-cvs repository extracted, skip
+ # the docs gluing
+ push @target, $self->{NOECHO} . '$(NOOP)';
+ }
+ push @targets, join "\n\t", @target;
+
+# # next target: cleanup the dependency file
+# @target = ('glue_pods_clean:');
+# push @target, '$(RM_F) glue_pods';
+# push @targets, join "\n\t", @target;
+
+ return join "\n\n", @targets, '';
+}
+
+sub glue_pod {
+
+ die "expecting 3 arguments: pm, pod, dst" unless @ARGV == 3;
+ my ($pm, $pod, $dst) = @ARGV;
+
+ # it's possible that the .pm file is not existing
+ # (e.g. ThreadMutex.pm is not created on unless
+ # $apr_config->{HAS_THREADS})
+ return unless -e $pm && -e $dst;
+
+ # have we already glued the doc?
+ exit 0 unless -s $pm == -s $dst;
+
+ # ExtUtils::Install::pm_to_blib removes the 'w' perms, so we can't
+ # just append the doc there
+ my $orig_mode = (stat $dst)[2];
+ my $rw_mode = 0666;
+
+ chmod $rw_mode, $dst or die "Can't chmod $rw_mode $dst: $!";
+ open my $pod_fh, "<$pod" or die "Can't open $pod: $!";
+ open my $dst_fh, ">>$dst" or die "Can't open $dst: $!";
+ print $dst_fh "\n"; # must add one line separation
+ print $dst_fh (<$pod_fh>);
+ close $pod_fh;
+ close $dst_fh;
+ # restore the perms
+ chmod $orig_mode, $dst or die "Can't chmod $orig_mode $dst: $!";
+}
+
+sub ModPerl::BuildMM::MY::post_initialize {
+ my $self = shift;
+ $build ||= build_config();
+ my $pm = $self->{PM};
+
+ while (my ($k, $v) = each %PM) {
+ if (-e $k) {
+ $pm->{$k} = $v;
+ }
+ }
+
+ # prefix typemap with Apache2/ so when installed in the
+ # perl-lib-tree it won't be picked by non-mod_perl modules
+ if (exists $pm->{'lib/typemap'} ) {
+ $pm->{'lib/typemap'} = '$(INST_ARCHLIB)/auto/Apache2/typemap';
+ }
+
+ '';
+}
+
+my $apr_config;
+
+sub ModPerl::BuildMM::MY::libscan {
+ my ($self, $path) = @_;
+
+ $apr_config ||= $build->get_apr_config();
+
+ if ($path =~ m/(Thread|Global)(Mutex|RWLock)/) {
+ return unless $apr_config->{HAS_THREADS};
+ }
+
+ return '' if $path =~ /DummyVersions.pm/;
+
+ return '' if $path =~ m/\.pl$/;
+ return '' if $path =~ m/~$/;
+ return '' if $path =~ /\B\.svn\b/;
+
+ $path;
+}
+
+1;
diff --git a/2_0_13/lib/ModPerl/BuildOptions.pm b/2_0_13/lib/ModPerl/BuildOptions.pm
new file mode 100644
index 0000000..b54bd8e
--- /dev/null
+++ b/2_0_13/lib/ModPerl/BuildOptions.pm
@@ -0,0 +1,271 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::BuildOptions;
+
+use strict;
+use warnings;
+
+use Apache2::Build ();
+use Apache::TestTrace;
+use Config ();
+my $param_qr = qr([\s=]+);
+
+use constant VERBOSE => 1;
+use constant UNKNOWN_FATAL => 2;
+
+use File::Spec;
+
+sub init {
+ my ($class, $build) = @_;
+
+ #@ARGV should override what's in .makepl_args.mod_perl2
+ #but @ARGV might also override the default MP_OPTS_FILE
+ #so snag that first
+ parse($build, [grep { /^MP_OPTIONS_FILE/ } @ARGV]);
+ parse_file($build);
+ parse_argv($build);
+
+ # if AP_PREFIX is used apxs and apr-config from the apache build
+ # tree won't work, so it can't co-exist with APXS and APR_CONFIG
+ # options
+ if ($build->{MP_AP_PREFIX} and $build->{MP_APXS}) {
+ error "You need to pass either MP_AP_PREFIX or MP_APXS, but not both";
+ die "\n";
+ }
+ if ($build->{MP_AP_PREFIX} and $build->{MP_APR_CONFIG}) {
+ error "You need to pass either MP_AP_PREFIX or MP_APR_CONFIG, " .
+ "but not both";
+ die "\n";
+ }
+
+ if ($build->{MP_DEBUG} and $build->{MP_USE_GTOP} and !$build->find_gtop) {
+ error "Can't find libgtop, resetting MP_USE_GTOP=0";
+ $build->{MP_USE_GTOP} = 0;
+ }
+
+ unless ($build->{MP_USE_DSO} or $build->{MP_USE_STATIC}) {
+ # default to DSO
+ $build->{MP_USE_DSO} = 1;
+ }
+
+ $build->{MP_GENERATE_XS} = 1 unless exists $build->{MP_GENERATE_XS};
+
+ # define MP_COMPAT_1X unless explicitly told to disable it
+ $build->{MP_COMPAT_1X} = 1
+ unless exists $build->{MP_COMPAT_1X} && !$build->{MP_COMPAT_1X};
+
+ # try to find apxs
+ if (!$build->{MP_AP_PREFIX} && !$build->{MP_APXS}) {
+ $build->find_apxs_util();
+
+ # make a last ditch effort to find apxs in $ENV{PATH}
+ if (!$build->{MP_APXS}) {
+ my @paths = split(/$Config::Config{path_sep}/, $ENV{PATH});
+ my $potential_apxs;
+ while (!$potential_apxs) {
+ last if scalar(@paths) == 0; # don't loop endlessly
+ $potential_apxs = File::Spec->catfile(shift @paths, 'apxs');
+ $potential_apxs .= '.bat' if Apache2::Build::WIN32();
+ if (-e $potential_apxs && -x $potential_apxs) {
+ $build->{MP_APXS} = $potential_apxs;
+ } else {
+ undef $potential_apxs;
+ }
+ }
+ }
+ }
+}
+
+sub parse {
+ my ($build, $lines, $opts) = @_;
+
+ $opts = VERBOSE|UNKNOWN_FATAL unless defined $opts;
+ my $table = table();
+ my @unknown;
+ my $continue = "";
+
+ my @data = ();
+ for (@$lines) {
+ chomp;
+ s/^\s+//; s/\s+$//;
+ next if /^\#/ || /^$/;
+ last if /^__END__/;
+
+ # more than one entry on the same line (but make sure to leave
+ # -DMP_* alone)
+ push @data, split /(?=\WMP_)/, $_;
+ }
+
+ for (@data) {
+ #XXX: this "parser" should be more robust
+
+ s/^\s+//; s/\s+$//;
+
+ $_ = "$continue $_" if $continue;
+
+ #example: +"MP_CCOPTS=-Werror" if $] >= 5.007
+ if (s/^\+//) {
+ $_ = eval $_;
+ }
+
+ if (/^MP_/) {
+ my ($key, $val) = split $param_qr, $_, 2;
+ $val ||= "" unless defined $val && $val eq '0';
+ $continue = $val =~ s/\\$// ? $key : "";
+
+ if (!$table->{$key} and $opts & UNKNOWN_FATAL) {
+ my $usage = usage();
+ die "Unknown Option: $key\nUsage:\n$usage\n";
+ }
+
+ if ($key eq 'MP_APXS') {
+ $val = File::Spec->canonpath(File::Spec->rel2abs($val));
+ }
+
+ if ($key eq 'MP_AP_PREFIX') {
+ $val = File::Spec->canonpath(File::Spec->rel2abs($val));
+
+ if (Apache2::Build::WIN32()) {
+ # MP_AP_PREFIX may not contain spaces
+ require Win32;
+ $val = Win32::GetShortPathName($val);
+ }
+
+ if (!$val || !-d $val) {
+ error "MP_AP_PREFIX must point to a valid directory.";
+ die "\n";
+ }
+ }
+
+ if ($table->{$key}->{append}){
+ $build->{$key} = join " ", grep $_, $build->{$key}, $val;
+ }
+ else {
+ $build->{$key} = $val;
+ }
+
+ print " $key = $val\n" if $opts & VERBOSE;
+ }
+ else {
+ push @unknown, $_;
+ }
+ }
+
+ return \@unknown;
+}
+
+sub parse_file {
+ my $build = shift;
+
+ my $fh;
+ my @dirs = qw(./ ../ ./. ../.);
+ push @dirs, "$ENV{HOME}/." if exists $ENV{HOME};
+ my @files = map { $_ . 'makepl_args.mod_perl2' } @dirs;
+ unshift @files, $build->{MP_OPTIONS_FILE} if $build->{MP_OPTIONS_FILE};
+
+ for my $file (@files) {
+ if (open $fh, $file) {
+ $build->{MP_OPTIONS_FILE} = $file;
+ last;
+ }
+ $fh = undef;
+ }
+
+ return unless $fh;
+
+ print "Reading Makefile.PL args from $build->{MP_OPTIONS_FILE}\n";
+ my $unknowns = parse($build, [<$fh>]);
+ push @ARGV, @$unknowns if $unknowns;
+
+ close $fh;
+}
+
+sub parse_argv {
+ my $build = shift;
+ return unless @ARGV;
+
+ my @args = @ARGV;
+ @ARGV = ();
+
+ print "Reading Makefile.PL args from \@ARGV\n";
+ my $unknowns = parse($build, \@args);
+ push @ARGV, @$unknowns if $unknowns;
+}
+
+sub usage {
+ my $table = table();
+ my @opts = map { "$_ - $table->{$_}->{val}" } sort keys %$table;
+ join "\n", @opts;
+}
+
+sub parse_table {
+ my ($fh) = @_;
+ my %table;
+ local $_;
+
+ while (<$fh>) {
+ chomp;
+ s/^\s+//; s/\s+$//;
+ next if /^\#/ || /^$/;
+ last if /^__END__/;
+ my ($key, $append, $val) = split /\s+/, $_, 3;
+ $table{'MP_' . $key} = { append => $append, val => $val };
+ }
+
+ return \%table;
+}
+
+my $Table;
+
+sub table {
+ $Table ||= parse_table(\*DATA);
+}
+
+1;
+
+# __DATA__ format:
+# key append description
+# where:
+# key: is the option name
+# append: is whether we want to replace a default option (0)
+# or append the arg to the option (1)
+# desc: description for this option
+
+__DATA__
+USE_GTOP 0 Link with libgtop and enable libgtop reporting
+DEBUG 0 Turning on debugging (-g -lperld) and tracing
+MAINTAINER 0 Maintainer mode: DEBUG=1 -DAP_DEBUG -Wall ...
+CCOPTS 1 Add to compiler flags
+TRACE 0 Turn on tracing
+USE_DSO 0 Build mod_perl as a dso
+USE_STATIC 0 Build mod_perl static
+PROMPT_DEFAULT 0 Accept default value for all would-be prompts
+OPTIONS_FILE 0 Read options from given file
+STATIC_EXTS 0 Build Apache2::*.xs as static extensions
+APXS 0 Path to apxs
+AP_DESTDIR 0 Destination for Apache specific mod_perl bits
+AP_PREFIX 0 Apache installation or source tree prefix
+AP_CONFIGURE 0 Apache ./configure arguments
+APR_CONFIG 0 Path to apr-config
+APU_CONFIG 0 Path to apu-config
+XS_GLUE_DIR 1 Directories containing extension glue
+INCLUDE_DIR 1 Add directories to search for header files
+GENERATE_XS 0 Generate XS code based on httpd version
+LIBNAME 0 Name of the modperl dso library (default is mod_perl)
+COMPAT_1X 0 Compile-time mod_perl 1.0 backcompat (default is on)
+APR_LIB 0 Lib used to build APR::* on Win32 (default is aprext)
+NO_THREADS 0 Build mod_perl without thread support with httpd >= 2.4
diff --git a/2_0_13/lib/ModPerl/CScan.pm b/2_0_13/lib/ModPerl/CScan.pm
new file mode 100644
index 0000000..4985ef0
--- /dev/null
+++ b/2_0_13/lib/ModPerl/CScan.pm
@@ -0,0 +1,1010 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package ModPerl::CScan;
+
+require Exporter;
+use Config '%Config';
+use File::Basename;
+
+# NOTE to distributors: this module is needed only for mp2 developers,
+# it's not a requirement for mod_perl users
+use Data::Flow qw(0.05);
+
+use strict; # Earlier it catches ISA and EXPORT.
+
+@ModPerl::CScan::ISA = qw(Exporter Data::Flow);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+
+@ModPerl::CScan::EXPORT = qw(
+ );
+@ModPerl::CScan::EXPORT_OK = qw(
+ );
+# this flag tells cpp to only output macros
+$ModPerl::CScan::MACROS_ONLY = '-dM';
+
+$ModPerl::CScan::VERSION = '0.75';
+
+my (%keywords,%style_keywords);
+for (qw(asm auto break case char continue default do double else enum
+ extern float for fortran goto if int long register return short
+ sizeof static struct switch typedef union unsigned signed while void volatile)) {
+ $keywords{$_}++;
+}
+for (qw(bool class const delete friend inline new operator overload private
+ protected public virtual)) {
+ $style_keywords{'C++'}{$_}++;
+}
+for (qw(__func__ _Complex _Imaginary _Bool inline restrict)) {
+ $style_keywords{'C9X'}{$_}++;
+}
+for (qw(inline const asm noreturn section
+ constructor destructor unused weak)) {
+ $style_keywords{'GNU'}{$_}++;
+ $style_keywords{'GNU'}{"__$ {_}__"}++;
+}
+ $style_keywords{'GNU'}{__attribute__}++;
+ $style_keywords{'GNU'}{__extension__}++;
+ $style_keywords{'GNU'}{__consts}++;
+ $style_keywords{'GNU'}{__const}++;
+ $style_keywords{'GNU'}{__restrict}++;
+
+my $recipes
+ = { Defines => { default => '' },
+ cppstdin => { default => $Config{cppstdin} },
+ cppflags => { default => $Config{cppflags} },
+ cppminus => { default => $Config{cppminus} },
+ c_styles => { default => [qw(C++ GNU C9X)] },
+ add_cppflags => { default => '' },
+ keywords => { prerequisites => ['c_styles'],
+ output => sub {
+ my %kw = %keywords;
+ my %add;
+ for ( @{ shift->{c_styles} } ) {
+ %add = %{ $style_keywords{$_} };
+ %kw = (%kw, %add);
+ }
+ \%kw;
+ }, },
+ 'undef' => { default => undef },
+ filename_filter => { default => undef },
+ full_text => { class_filter => [ 'text', 'C::Preprocessed',
+ qw(undef filename Defines includeDirs Cpp)] },
+ text => { class_filter => [ 'text', 'C::Preprocessed',
+ qw(filename_filter filename Defines includeDirs Cpp)] },
+ text_only_from => { class_filter => [ 'text_only_from', 'C::Preprocessed',
+ qw(filename_filter filename Defines includeDirs Cpp)] },
+ includes => { filter => [ \&includes,
+ qw(filename Defines includeDirs Cpp) ], },
+ includeDirs => { prerequisites => ['filedir'],
+ output => sub {
+ my $data = shift;
+ [ $data->{filedir}, '/usr/local/include', '.'];
+ } },
+ Cpp => { prerequisites => [qw(cppminus add_cppflags cppflags cppstdin)],
+ output => sub {
+ my $data = shift;
+ return { cppstdin => $data->{cppstdin},
+ cppflags => "$data->{cppflags} $data->{add_cppflags}",
+ cppminus => $data->{cppminus} };
+ } },
+ filedir => { output => sub { dirname ( shift->{filename} || '.' ) } },
+ sanitized => { filter => [ \&sanitize, 'text'], },
+ toplevel => { filter => [ \&top_level, 'sanitized'], },
+ full_sanitized => { filter => [ \&sanitize, 'full_text'], },
+ full_toplevel => { filter => [ \&top_level, 'full_sanitized'], },
+ no_type_decl => { filter => [ \&remove_type_decl, 'toplevel'], },
+ typedef_chunks => { filter => [ \&typedef_chunks, 'full_toplevel'], },
+ struct_chunks => { filter => [ \&struct_chunks, 'full_toplevel'], },
+ typedefs_whited => { filter => [ \&typedefs_whited,
+ 'full_sanitized', 'typedef_chunks',
+ 'keywords_rex'], },
+ typedef_texts => { filter => [ \&typedef_texts,
+ 'full_text', 'typedef_chunks'], },
+ struct_texts => { filter => [ \&typedef_texts,
+ 'full_text', 'struct_chunks'], },
+ typedef_hash => { filter => [ \&typedef_hash,
+ 'typedef_texts', 'typedefs_whited'], },
+ typedef_structs => { filter => [ \&typedef_structs,
+ 'typedef_hash', 'struct_texts'], },
+ typedefs_maybe => { filter => [ sub {[keys %{+shift}]},
+ 'typedef_hash'], },
+ defines_maybe => { filter => [ \&defines_maybe, 'filename'], },
+ defines_no_args => { prerequisites => ['defines_maybe'],
+ output => sub { shift->{defines_maybe}->[0] }, },
+ defines_args => { prerequisites => ['defines_maybe'],
+ output => sub { shift->{defines_maybe}->[1] }, },
+
+ defines_full => { filter => [ \&defines_full,
+ qw(filename Defines includeDirs Cpp) ], },
+ defines_no_args_full => { prerequisites => ['defines_full'],
+ output => sub { shift->{defines_full}->[0] }, },
+ defines_args_full => { prerequisites => ['defines_full'],
+ output => sub { shift->{defines_full}->[1] }, },
+
+ decl_inlines => { filter => [ \&functions_in, 'no_type_decl'], },
+ inline_chunks => { filter => [ sub { shift->[0] }, 'decl_inlines'], },
+ inlines => { filter => [ \&from_chunks, 'inline_chunks', 'text'], },
+ decl_chunks => { filter => [ sub { shift->[1] }, 'decl_inlines'], },
+ decls => { filter => [ \&from_chunks, 'decl_chunks', 'text'], },
+ fdecl_chunks => { filter => [ sub { shift->[4] }, 'decl_inlines'], },
+ fdecls => { filter => [ \&from_chunks, 'fdecl_chunks', 'text'], },
+ mdecl_chunks => { filter => [ sub { shift->[2] }, 'decl_inlines'], },
+ mdecls => { filter => [ \&from_chunks, 'mdecl_chunks', 'text'], },
+ vdecl_chunks => { filter => [ sub { shift->[3] }, 'decl_inlines'], },
+ vdecls => { filter => [ \&from_chunks, 'vdecl_chunks', 'text'], },
+ vdecl_hash => { filter => [ \&vdecl_hash, 'vdecls', 'mdecls' ], },
+ parsed_fdecls => { filter => [ \&do_declarations, 'fdecls',
+ 'typedef_hash', 'keywords'], },
+ parsed_inlines => { filter => [ \&do_declarations, 'inlines',
+ 'typedef_hash', 'keywords'], },
+ keywords_rex => { filter => [ sub { my @k = keys %{ shift() };
+ local $" = '|';
+ my $r = "(?:@k)";
+ eval 'qr/$r/' or $r # Older Perls
+ }, 'keywords'], },
+ };
+
+sub from_chunks {
+ my $chunks = shift;
+ my $txt = shift;
+ my @out;
+ my $i = 0;
+ while ($i < @$chunks) {
+ push @out, substr $txt, $chunks->[$i], $chunks->[ $i + 1 ] - $chunks->[$i];
+ $i += 2;
+ }
+ \@out;
+}
+
+#sub process { request($recipes, @_) }
+# Preloaded methods go here.
+
+sub includes {
+ my %seen;
+ my $stream = new C::Preprocessed (@_)
+ or die "Cannot open pipe from cppstdin: $!\n";
+
+ while (<$stream>) {
+ next unless m(^\s*\#\s* # Leading hash
+ (line\s*)? # 1: Optional line
+ ([0-9]+)\s* # 2: Line number
+ (.*) # 3: The rest
+ )x;
+ my $include = $3;
+ $include = $1 if $include =~ /"(.*)"/; # Filename may be in quotes
+ $include =~ s,\\\\,/,g if $^O eq 'os2';
+ $seen{$include}++ if $include ne "";
+ }
+ [keys %seen];
+}
+
+sub defines_maybe {
+ my $file = shift;
+ my ($mline,$line,%macros,%macrosargs,$sym,$args);
+ open(C, $file) or die "Cannot open file $file: $!\n";
+ while (not eof(C) and $line = <C>) {
+ next unless
+ ( $line =~ s[
+ ^ \s* \# \s* # Start of directive
+ define \s+
+ (\w+) # 1: symbol
+ (?:
+ \( (.*?) \s* \) # 2: Minimal match for arguments
+ # in parenths (without trailing
+ # spaces)
+ )? # optional, no grouping
+ \s* # rest is the definition
+ ([\s\S]*) # 3: the rest
+ ][]x );
+ ($sym, $args, $mline) = ($1, $2, $3);
+ $mline .= <C> while not eof(C) and $mline =~ s/\\\n/\n/;
+ chomp $mline;
+ #print "sym: `$sym', args: `$args', mline: `$mline'\n";
+ if (defined $args) {
+ $macrosargs{$sym} = [ [split /\s*,\s*/, $args], $mline];
+ } else {
+ $macros{$sym} = $mline;
+ }
+ }
+ close(C) or die "Cannot close file $file: $!\n";
+ [\%macros, \%macrosargs];
+}
+
+sub defines_full {
+ my $Cpp = $_[3];
+ my ($mline,$line,%macros,%macrosargs,$sym,$args);
+
+ # save the old cppflags and add the flag for only ouputting macro definitions
+ my $old_cppstdin = $Cpp->{'cppstdin'};
+ $Cpp->{'cppstdin'} = $old_cppstdin . " " . $ModPerl::CScan::MACROS_ONLY;
+
+ my $stream = new C::Preprocessed (@_)
+ or die "Cannot open pipe from cppstdin: $!\n";
+
+ while (defined ($line = <$stream>)) {
+ next unless
+ ( $line =~ s[
+ ^ \s* \# \s* # Start of directive
+ define \s+
+ (\w+) # 1: symbol
+ (?:
+ \( (.*?) \s* \) # 2: Minimal match for arguments
+ # in parenths (without trailing
+ # spaces)
+ )? # optional, no grouping
+ \s* # rest is the definition
+ ([\s\S]*) # 3: the rest
+ ][]x );
+ ($sym, $args, $mline) = ($1, $2, $3);
+ $mline .= <$stream> while ($mline =~ s/\\\n/\n/);
+ chomp $mline;
+#print STDERR "sym: `$sym', args: `$args', mline: `$mline'\n";
+ if (defined $args) {
+ $macrosargs{$sym} = [ [split /\s*,\s*/, $args], $mline];
+ } else {
+ $macros{$sym} = $mline;
+ }
+ }
+ # restore the original cppflags
+ $Cpp->{'cppstdin'} = $old_cppstdin;
+ [\%macros, \%macrosargs];
+}
+
+sub typedef_chunks { # Input is toplevel, output: starts and ends
+ my $txt = shift;
+ pos $txt = 0;
+ my ($b, $e, @out);
+ while ($txt =~ /\btypedef\b/g) {
+ push @out, pos $txt;
+ $txt =~ /(?=;)|\Z/g;
+ push @out, pos $txt;
+ }
+ \@out;
+}
+
+sub struct_chunks {
+ my $txt = shift;
+ pos $txt = 0;
+ my ($b, $e, @out);
+ while ($txt =~ /\b(?=struct\s*(\w*\s*)?\{)/g) {
+ push @out, pos $txt;
+ $txt =~ /(?=;)|\Z/g;
+ push @out, pos $txt;
+ }
+ \@out;
+}
+
+sub typedefs_whited { # Input is sanitized text, and list of beg/end.
+ my @lst = @{$_[1]};
+ my @out;
+ my ($b, $e);
+ while ($b = shift @lst) {
+ $e = shift @lst;
+ push @out, whited_decl($_[2], substr $_[0], $b, $e - $b);
+ }
+ \@out;
+}
+
+sub structs_whited {
+ my @lst = @{$_[1]};
+ my @out;
+ my ($b, $e, $in);
+ while ($b = shift @lst) {
+ $e = shift @lst;
+ $in = substr $_[0], $b, $e - $b;
+ $in =~ s/^(struct\s*(\w*\s*)?)(.*)$/$1 . " " x length($3)/es;
+ push @out, $in;
+ }
+ \@out;
+}
+
+sub typedef_texts {
+ my ($txt, $chunks) = (shift, shift);
+ my ($b, $e, $in, @out);
+ my @in = @$chunks;
+ while (($b, $e) = splice @in, 0, 2) {
+ $in = substr($txt, $b, $e - $b);
+ # remove any remaining directives
+ $in =~ s/^ ( \s* \# .* ( \\ $ \n .* )* ) / ' ' x length($1)/xgem;
+ push @out, $in;
+ }
+ \@out;
+}
+
+sub typedef_hash {
+ my ($typedefs, $whited) = (shift,shift);
+ my %out;
+
+ loop:
+ for my $o (0..$#$typedefs) {
+ my $wh = $whited->[$o];
+ my $td = $typedefs->[$o];
+#my $verb = $td =~ /apr_child_errfn_t/ ? 1 : 0;
+#warn "$wh || $td\n" if $verb;
+ if ($wh =~ /,/ or not $wh =~ /\w/) { # Hard case, guessimates ...
+ # Determine whether the new thingies are inside parens
+ $wh =~ /,/g;
+ my $p = pos $wh;
+ my ($s, $e);
+ if (matchingbrace($wh)) { # Inside. Easy part: just split on /,/...
+ $e = pos($wh) - 1;
+ $s = $e;
+ my $d = 0;
+ # Skip back
+ while (--$s >= 0) {
+ my $c = substr $wh, $s, 1;
+ if ($c =~ /[\(\{\[]/) {
+ $d--;
+ } elsif ($c =~ /[\)\]\}]/) {
+ $d++;
+ }
+ last if $d < 0;
+ }
+ if ($s < 0) { # Should not happen
+ warn("panic: could not match braces in\n\t$td\nwhited as\n\t$wh\n");
+ next loop;
+ }
+ $s++;
+ } else { # We are at toplevel
+ # We need to skip back all the modifiers attached to the first thingy
+ # Guesstimates: everything after the first '*' (inclusive)
+ pos $wh = 0;
+ $wh = /(?=\w)/g;
+ my $ws = pos $wh;
+ my $pre = substr $wh, 0, $ws;
+ $s = $ws;
+ $s = pos $pre if $pre =~ /(?=\*)/g;
+ $e = length $wh;
+ }
+ # Now: need to split $td based on commas in $wh!
+ # And need to split each chunk of $td based on word in the chunk of $wh!
+ my $td_decls = substr($td, $s, $e - $s);
+ my ($pre, $post) = (substr($td, 0, $s), substr($td, $e));
+ my $wh_decls = substr($wh, $s, $e - $s);
+ my @wh_decls = split /,/, $wh_decls;
+ my $td_s = 0;
+ my (@td_decl, @td_pre, @td_post, @td_word);
+ for my $wh_d (@wh_decls) {
+ my $td_d = substr $td, $td_s, length $wh_d;
+ push @td_decl, $td_d;
+ $wh_d =~ /(\w+)/g;
+ push @td_word, $1;
+ push @td_post, substr $td_d, pos($wh_d);
+ push @td_pre, substr $td_d, pos($wh_d) - length $1, length $1;
+ $td_s += 1 + length $wh_d; # Skip over ','
+ }
+ for my $i (0..$#wh_decls) {
+ my $p = "$td_post[$i]$post";
+ $p = '' unless $p =~ /\S/;
+ $out{$td_word[$i]} = ["$pre$td_pre[$i]", $p];
+ }
+ } elsif ($td =~ /\(\s* \*? \s* ([^)]+) \s* \) \s* \(.*\)/gxs){ # XXX: function pointer typedef
+ $out{$1} = ['XXX: pre_foo', 'XXX: post_bar']; # XXX: not sure what to stuff here
+ #warn "[$1] [$td]" if $verb;
+ } else { # Only one thing defined...
+ $wh =~ /(\w+)/g;
+ my $e = pos $wh;
+ my $s = $e - length $1;
+ my $type = $1;
+ my $pre = substr $td, 0, $s;
+ my $post = substr $td, $e, length($td) - $e;
+ $post = '' unless $post =~ /\S/;
+ $out{$type} = [$pre, $post];
+ }
+
+ #die if $verb;
+
+ }
+ \%out;
+}
+
+sub typedef_structs {
+ my ($typehash, $structs) = @_;
+ my %structs;
+ for (0 .. $#$structs) {
+ my $in = $structs->[$_];
+ my $key;
+ next unless $in =~ /^struct\s*(\w+)/;
+ next unless $in =~ s{^(struct\s*)(\w+)}{
+ $key = "struct $2";
+ $1 . " " x length($2)
+ }e;
+ my $name = parse_struct($in, \%structs);
+ $structs{$key} = defined($name) ? $structs{$name} : undef;
+ }
+ while (my ($key, $text) = each %$typehash) {
+ my $name = parse_struct($text->[0], \%structs);
+ $structs{$key} = defined($name) ? $structs{$name} : undef;
+ }
+ \%structs;
+}
+
+sub parse_struct {
+ my ($in, $structs) = @_;
+ my ($b, $e, $chunk, $vars, $struct, $structname);
+ return "$1 $2" if $in =~ /
+ ^ \s* (struct | union) \s+ (\w+) \s* $
+ /x;
+ ($structname, $in) = $in =~ /
+ ^ \s* ( (?: struct | union ) (?: \s+ \w+ )? ) \s* { \s* (.*?) \s* } \s* $
+ /gisx or return;
+ $structname .= " _ANON" unless $structname =~ /\s/;
+ $structname .= " 0" if exists $structs->{$structname};
+ $structname =~ s/(\d+$)/$1 + 1/e while exists $structs->{$structname};
+ $structname =~ s/\s+/ /g;
+ $b = 0;
+ while ($in =~ /(\{|;|$)/g) {
+ matchingbrace($in), next if $1 eq '{';
+ $e = pos($in);
+ next if $b == $e;
+ $chunk = substr($in, $b, $e - $b);
+ $b = $e;
+ if ($chunk =~ /\G\s*(struct|union|enum).*\}/gs) {
+ my $term = pos $chunk;
+ my $name = parse_struct(substr($chunk, 0, $term), $structs);
+ $vars = parse_vars(join ' ', $name, substr $chunk, $term);
+ } else {
+ $vars = parse_vars($chunk);
+ }
+ push @$struct, @{$vars||[]};
+ }
+ $structs->{$structname} = $struct;
+ $structname;
+}
+
+sub parse_vars {
+ my $in = shift;
+ my ($vars, $type, $word, $id, $post, $func);
+
+ while ($in =~ /\G\s*([\[;,(]|\*+|:\s*\d+|\S+?\b|$)\s*/gc) {
+ $word = $1;
+ if ($word eq ';' || $word eq '') {
+ next unless defined $id;
+ $type = 'int' unless defined $type; # or is this an error?
+ push @$vars, [ $type, $post, $id ];
+ ($type, $post, $id, $func) = (undef, undef, undef);
+ } elsif ($word eq ',') {
+ warn "panic: expecting name before comma in '$in'\n" unless defined $id;
+ $type = 'int' unless defined $type; # or is this an error?
+ push @$vars, [ $type, $post, $id ];
+ $type =~ s/[ *]*$//;
+ $id = undef;
+ } elsif ($word eq '[') {
+ warn "panic: expecting name before '[' in '$in'\n" unless defined $id;
+ $type = 'int' unless defined $type; # or is this an error?
+ my $b = pos $in;
+ matchingbrace($in);
+ $post .= $word . substr $in, $b, pos($in) - $b;
+ } elsif ($word eq '(') {
+ # simple hack for function pointers
+ $type = join ' ', grep defined, $type, $id if defined $id;
+ $type = 'int' unless defined $type;
+ if ($in =~ /\G\s*(\*[\s\*]*?)\s*(\w+)[\[\]\d\s]*(\)\s*\()/gc) {
+ $type .= "($1";
+ $id = $2;
+ $post = $3;
+ my $b = pos $in;
+ matchingbrace($in);
+ $post .= substr $in, $b, pos($in) - $b;
+ } else {
+ warn "panic: can't parse function pointer declaration in '$in'\n";
+ return;
+ }
+ } elsif ($word =~ /^:/) {
+ # bitfield
+ $type = 'int' unless defined $type;
+ $post .= $word;
+ } else {
+ if (defined $post) {
+ if ($func) {
+ $post .= $word;
+ } else {
+ warn "panic: not expecting '$word' after array bounds in '$in'\n";
+ }
+ } else {
+ $type = join ' ', grep defined, $type, $id if defined $id;
+ $id = $word;
+ }
+ }
+ }
+unless ($vars) {
+ warn sprintf "failed on <%s> with type=<%s>, id=<%s>, post=<%s> at pos=%d\n",
+ $in, $type, $id, $post, pos($in);
+}
+ $vars;
+}
+
+sub vdecl_hash {
+ my ($vdecls, $mdecls) = @_;
+ my %vdecl_hash;
+ for (@$vdecls, @$mdecls) {
+ next if /[()]/; # ignore functions, and function pointers
+ my $copy = $_;
+ next unless $copy =~ s/^\s*extern\s*//;
+ my $vars = parse_vars($copy);
+ $vdecl_hash{$_->[2]} = [ @$_[0, 1] ] for @$vars;
+ }
+ \%vdecl_hash;
+}
+
+# The output is the list of list of inline chunks and list of
+# declaration chunks.
+
+sub functions_in { # The arg is text without type declarations.
+ my $in = shift; # remove_type_decl(top_level(sanitize($txt)));
+ # What remains now consists of variable and function declarations,
+ # and inline functions.
+ $in =~ /(?=\S)/g;
+ my ($b, $e, $b1, $e1, @inlines, @decls, @mdecls, @fdecls, @vdecls);
+ $b = pos $in;
+ my $chunk;
+ while (defined($b) && $b != length $in) {
+ $in =~ /;/g or pos $in = $b, $in =~ /.*\S|\Z/g ; # Or last non-space
+ $e = pos $in;
+ $chunk = substr $in, $b, $e - $b;
+ # Now subdivide the chunk.
+ #
+ # What we got is one chunk, probably finished by `;'. Whoever, it
+ # may start with several inline functions.
+ #
+ # Note that inline functions contain ( ) { } in the stripped version.
+ $b1 = 0;
+ while ($chunk =~ /\(\s*\)\s*\{\s*\}/g) {
+ $e1 = pos $chunk;
+ push @inlines, $b + $b1, $b + $e1;
+ $chunk =~ /(?=\S)/g;
+ $b1 = pos $chunk;
+ $b1 = length $chunk, last unless defined $b1;
+ }
+ if ($e - $b - $b1 > 0) {
+ my ($isvar, $isfunc) = (1, 1);
+ substr ($chunk, 0, $b1) = '';
+ if ($chunk =~ /,/) { # Contains multiple declarations.
+ push @mdecls, $b + $b1, $e;
+ } else { # Non-multiple.
+ # Since leading \s* is not optimized, this is quadratic!
+ $chunk =~ s{
+ ( ( const | __const
+ | __attribute__ \s* \( \s* \)
+ ) \s* )* ( ; \s* )? \Z # Strip from the end
+ }()x;
+ $chunk =~ s/\s*\Z//;
+ if ($chunk =~ /\)\Z/) { # Function declaration ends on ")"!
+ if ($chunk !~ m{
+ \( .* \( # Multiple parenths
+ }x
+ and $chunk =~ / \w \s* \( /x) { # Most probably pointer to a function?
+ $isvar = 0;
+ }
+ } elsif ($chunk =~ /
+ ^ \s* (enum|struct|union|class) \s+ \w+ \s* $
+ /x) {
+ $isvar = $isfunc = 0;
+ }
+ if ($isvar) { # Heuristically variable
+ push @vdecls, $b + $b1, $e;
+ } elsif ($isfunc) {
+ push @fdecls, $b + $b1, $e;
+ }
+ }
+ push @decls, $b + $b1, $e if $isvar || $isfunc;
+ }
+ $in =~ /\G\s*/g ;
+ $b = pos $in;
+ }
+ [\@inlines, \@decls, \@mdecls, \@vdecls, \@fdecls];
+}
+
+# XXXX This is heuristical in many respects...
+# Recipe: remove all struct-ish chunks. Remove all array specifiers.
+# Remove GCC attribute specifiers.
+# What remains may contain function's arguments, old types, and newly
+# defined types.
+# Remove function arguments using heuristics methods.
+# Now out of several words in a row the last one is a newly defined type.
+
+sub whited_decl { # Input is sanitized.
+ my $keywords_rex = shift;
+ my $in = shift; # Text of a declaration
+
+ #typedef ret_type*(*func) -> typedef ret_type* (*func)
+ $in =~ s/\*\(\*/* \(*/;
+
+ my $rest = $in;
+ my $out = $in; # Whited out $in
+
+ # Remove all the structs
+ while ($out =~ /(\b(struct|union|class|enum)(\s+\w+)?\s*\{)/g) {
+ my $pos_start = pos($out) - length $1;
+
+ matchingbrace($out);
+ my $pos_end = pos $out;
+ substr($out, $pos_start, $pos_end - $pos_start) =
+ ' ' x ($pos_end - $pos_start);
+ pos $out = $pos_end;
+ }
+
+ # Deal with glibc's wierd ass __attribute__ tag. Just dump it.
+ # Maaaybe this should check to see if you're using GCC, but I don't
+ # think so since glibc is nice enough to do that for you. [MGS]
+ while ( $out =~ m/(\b(__attribute__|attribute)\s*\((?=\s*\())/g ) {
+ my $att_pos_start = pos($out) - length($1);
+
+ # Need to figure out where ((..)) ends.
+ matchingbrace($out);
+ my $att_pos_end = pos $out;
+
+ # Remove the __attribute__ tag.
+ substr($out, $att_pos_start, $att_pos_end - $att_pos_start) =
+ ' ' x ($att_pos_end - $att_pos_start);
+ pos $out = $att_pos_end;
+ }
+
+ # Remove arguments of functions (heuristics only).
+ # These things (start) arglist of a declared function:
+ # paren word comma
+ # paren word space non-paren
+ # paren keyword paren
+ # start a list of arguments. (May be "cdecl *myfunc"?) XXXXX ?????
+ while ( $out =~ /(\(\s*(\w+(,|\s*[^\)\s])|$keywords_rex\s*\)))/g ) {
+ my $pos_start = pos($out) - length($1);
+ pos $out = $pos_start + 1;
+ matchingbrace($out);
+ substr ($out, $pos_start + 1, pos($out) - 2 - $pos_start)
+ = ' ' x (pos($out) - 2 - $pos_start);
+ }
+ # Remove array specifiers
+ $out =~ s/(\[[\w\s\+]*\])/ ' ' x length $1 /ge;
+ my $tout = $out;
+ # Several words in a row cannot be new typedefs, but the last one.
+ $out =~ s/((\w+\**\s+)+(?=[^\s,;\[\{\)]))/ ' ' x length $1 /ge;
+ unless ($out =~ /\w/) {
+ # Probably a function-type declaration: typedef int f(int);
+ # Redo scan leaving the last word of the first group of words:
+ if ($tout =~ /(\w+\s+)*(\w+)\s*\(/g) {
+ $out = ' ' x (pos($tout) - length $2)
+ . $2 . ' ' x (length($tout) - pos($tout));
+ }
+ else {
+ # try a different approach to get the last type
+ my $len = length $tout;
+ # cut all non-words at the end of the definition
+ my $end = $tout =~ s/(\W*)$// ? length $1 : 0;
+ # remove everything but the last word
+ my $mid = $tout =~ s/.*?(\w*)$/$1/ ? length $1 : 0;
+ # restore the length
+ $out = $tout . ' ' x ($len - $mid);
+ }
+ # warn "function typedef\n\t'$in'\nwhited-out as\n\t'$out'\n";
+ }
+ warn "panic: length mismatch\n\t'$in'\nwhited-out as\n\t'$out'\n"
+ if length($in) != length $out;
+ # Sanity check
+ warn "panic: multiple types without intervening comma in\n\t'$in'\nwhited-out as\n\t'$out'\n"
+ if $out =~ /\w[^\w,]+\w/;
+ warn "panic: no types found in\n\t'$in'\nwhited-out as\n\t'$out'\n"
+ unless $out =~ /\w/;
+ $out
+}
+
+sub matchingbrace {
+ # pos($_[0]) is after the opening brace now
+ my $n = 0;
+ while ($_[0] =~ /([\{\[\(])|([\]\)\}])/g) {
+ $1 ? $n++ : $n-- ;
+ return 1 if $n < 0;
+ }
+ # pos($_[0]) is after the closing brace now
+ return; # false
+}
+
+sub remove_Comments_no_Strings { # We expect that no strings are around
+ my $in = shift;
+ $in =~ s,/(/.*|\*[\s\S]*?\*/),,g ; # C and C++
+ die "Unfinished comment" if $in =~ m,/\*, ;
+ $in;
+}
+
+sub sanitize { # We expect that no strings are around
+ my $in = shift;
+ # C and C++, strings and characters
+ $in =~ s{ / (
+ / .* # C++ style
+ |
+ \* [\s\S]*? \*/ # C style
+ ) # (1)
+ | '((?:[^\\\']|\\.)+)' # (2) Character constants
+ | "((?:[^\\\"]|\\.)*)" # (3) Strings
+ | ( ^ \s* \# .* # (4) Preprocessor
+ ( \\ $ \n .* )* ) # and continuation lines
+ } {
+ # We want to preserve the length, so that one may go back
+ defined $1 ? ' ' x (1 + length $1) :
+ defined $4 ? ' ' x length $4 :
+ defined $2 ? "'" . ' ' x length($2) . "'" :
+ defined $3 ? '"' . ' ' x length($3) . '"' : '???'
+ }xgem ;
+ die "Unfinished comment" if $in =~ m{ /\* }x;
+ $in;
+}
+
+sub top_level { # We expect argument is sanitized
+ # Note that this may remove the variable in declaration: int (*func)();
+ my $in = shift;
+ my $start;
+ my $out = $in;
+ while ($in =~ /[\[\{\(]/g ) {
+ $start = pos $in;
+ matchingbrace($in);
+ substr($out, $start, pos($in) - 1 - $start)
+ = ' ' x (pos($in) - 1 - $start);
+ }
+ $out;
+}
+
+sub remove_type_decl { # We suppose that the arg is top-level only.
+ my $in = shift;
+ $in =~ s/(\b__extension__)(\s+typedef\b)/(' ' x length $1) . $2/gse;
+ $in =~ s/(\btypedef\b.*?;)/' ' x length $1/gse;
+ # The following form may appear only in the declaration of the type itself:
+ $in =~
+ s/(\b(enum|struct|union|class)\b[\s\w]*\{\s*\}\s*;)/' ' x length $1/gse;
+ $in;
+}
+
+sub new {
+ my $class = shift;
+ my $out = SUPER::new $class $recipes;
+ $out->set(@_);
+ $out;
+}
+
+sub do_declarations {
+ my @d = map do_declaration($_, $_[1], $_[2]), @{ $_[0] };
+ \@d;
+}
+
+# Forth argument: if defined, there maybe no identifier. Generate one
+# basing on this argument.
+
+sub do_declaration {
+ my ($decl, $typedefs, $keywords, $argnum) = @_;
+ $decl =~ s/;?\s*$//;
+
+ my ($type, $typepre, $typepost, $ident, $args, $w, $pos, $repeater);
+ $decl =~ s/[\r\n]\s*/ /g;
+#warn "DECLAR [$decl][$argnum]\n";
+ $decl =~ s/^\s*__extension__\b\s*//;
+ $decl =~ s/^\s*extern\b\s*//;
+ $decl =~ s/^\s*__inline\b\s*//;
+ $pos = 0;
+ while ($decl =~ /(\w+)/g and ($typedefs->{$1} or $keywords->{$1})) {
+ $w = $1;
+ if ($w =~ /^(struct|class|enum|union)$/) {
+ $decl =~ /\G\s+\w+/g or die "`$w' is not followed by word in `$decl'";
+ }
+ $pos = pos $decl;
+ }
+#warn "pos: $pos\n";
+ pos $decl = $pos;
+ $decl =~ /\G[\s*]*\*/g or pos $decl = $pos;
+ $type = substr $decl, 0, pos $decl;
+ $decl =~ /\G\s*/g or pos $decl = length $type; # ????
+ $pos = pos $decl;
+#warn "pos: $pos\n";
+ if (defined $argnum) {
+ if ($decl =~ /\G(\w+)((\s*\[[^][]*\])*)/g) { # The best we can do with [2]
+ $ident = $1;
+ $repeater = $2;
+ $pos = pos $decl;
+ } else {
+ pos $decl = $pos = length $decl;
+ $type = $decl;
+ $ident = "arg$argnum";
+ }
+ } else {
+ die "Cannot process declaration `$decl' without an identifier"
+ unless $decl =~ /\G(\w+)/g;
+ $ident = $1;
+ $pos = pos $decl;
+ }
+#warn "pos: $pos\n";
+ $decl =~ /\G\s*/g or pos $decl = $pos;
+ $pos = pos $decl;
+#my $st = length $decl;
+#warn substr($decl, 0, $pos), "\n";
+#warn "pos: $pos $st\n";
+#warn "DECLAR [$decl][$argnum]\n";
+ if (pos $decl != length $decl) {
+ pos $decl = $pos;
+ die "Expecting parenth after identifier in `$decl'\nafter `",
+ substr($decl, 0, $pos), "'"
+ unless $decl =~ /\G\(/g;
+ my $argstring = substr($decl, pos($decl) - length $decl);
+ matchingbrace($argstring) or die "Cannot find matching parenth in `$decl'";
+ $argstring = substr($argstring, 0, pos($argstring) - 1);
+ $argstring =~ s/ ^ ( \s* void )? \s* $ //x;
+ $args = [];
+ my @args;
+ if ($argstring ne '') {
+ my $top = top_level $argstring;
+ my $p = 0;
+ my $arg;
+ while ($top =~ /,/g) {
+ $arg = substr($argstring, $p, pos($top) - 1 - $p);
+ $arg =~ s/^\s+|\s+$//gs;
+ push @args, $arg;
+ $p = pos $top;
+ }
+ $arg = substr $argstring, $p;
+ $arg =~ s/^\s+|\s+$//gs;
+ push @args, $arg;
+ }
+ my $i = 0;
+ for (@args) {
+ push @$args, do_declaration1($_, $typedefs, $keywords, $i++);
+ }
+ }
+ [$type, $ident, $args, $decl, $repeater];
+}
+
+sub do_declaration1 {
+ my ($decl, $typedefs, $keywords, $argnum) = @_;
+ $decl =~ s/;?\s*$//;
+#warn "DECLARO [$decl][$argnum]\n";
+ my ($type, $typepre, $typepost, $ident, $args, $w, $pos, $repeater);
+ $pos = 0;
+ while ($decl =~ /(\w+)/g and ($typedefs->{$1} or $keywords->{$1})) {
+ $w = $1;
+ if ($w =~ /^(struct|class|enum|union)$/) {
+ $decl =~ /\G\s+\w+/g or die "`$w' is not followed by word in `$decl'";
+ }
+ $pos = pos $decl;
+ }
+#warn "POS: $pos\n";
+ pos $decl = $pos;
+ $decl =~ /\G[\s*]*\*/g or pos $decl = $pos;
+ $type = substr $decl, 0, pos $decl;
+ $decl =~ /\G\s*/g or pos $decl = length $type; # ????
+ $pos = pos $decl;
+ if (defined $argnum) {
+ if ($decl =~ /\G(\w+)((\s*\[[^][]*\])*)/g) { # The best we can do with [2]
+ $ident = $1;
+ $repeater = $2;
+ $pos = pos $decl;
+ } else {
+ pos $decl = $pos = length $decl;
+ $type = $decl;
+ $ident = "arg$argnum";
+ }
+ } else {
+ die "Cannot process declaration `$decl' without an identifier"
+ unless $decl =~ /\G(\w+)/g;
+ $ident = $1;
+ $pos = pos $decl;
+ }
+ $decl =~ /\G\s*/g or pos $decl = $pos;
+ $pos = pos $decl;
+#warn "DECLAR1 [$decl][$argnum]\n";
+#my $st = length $decl;
+#warn substr($decl, 0, $pos), "\n";
+#warn "pos: $pos $st\n";
+ if (pos $decl != length $decl) {
+ pos $decl = $pos;
+ die "Expecting parenth after identifier in `$decl'\nafter `",
+ substr($decl, 0, $pos), "'"
+ unless $decl =~ /\G\(/g;
+ my $argstring = substr($decl, pos($decl) - length $decl);
+ matchingbrace($argstring) or die "Cannot find matching parenth in `$decl'";
+ $argstring = substr($argstring, 0, pos($argstring) - 1);
+ $argstring =~ s/ ^ ( \s* void )? \s* $ //x;
+ $args = [];
+ my @args;
+ if ($argstring ne '') {
+ my $top = top_level $argstring;
+ my $p = 0;
+ my $arg;
+ while ($top =~ /,/g) {
+ $arg = substr($argstring, $p, pos($top) - 1 - $p);
+ $arg =~ s/^\s+|\s+$//gs;
+ push @args, $arg;
+ $p = pos $top;
+ }
+ $arg = substr $argstring, $p;
+ $arg =~ s/^\s+|\s+$//gs;
+ push @args, $arg;
+ }
+ my $i = 0;
+ for (@args) {
+ push @$args, do_declaration1($_, $typedefs, $keywords, $i++);
+ }
+ }
+ [$type, $ident, $args, $decl, $repeater];
+}
+
+############################################################
+
+package C::Preprocessed;
+use Symbol;
+use File::Basename;
+use Config;
+use constant WIN32 => $^O eq 'MSWin32';
+
+sub new {
+ die "usage: C::Preprocessed->new(filename[, defines[, includes[, cpp]]])"
+ if @_ < 2 or @_ > 5;
+ my ($class, $filename, $Defines, $Includes, $Cpp)
+ = (shift, shift, shift, shift, shift);
+ $Cpp ||= \%Config::Config;
+ my $filedir = dirname $filename || '.';
+ $Includes ||= [$filedir, '/usr/local/include', '.'];
+ my $addincludes = "";
+ $addincludes = "-I" . join(" -I", @$Includes)
+ if defined $Includes and @$Includes;
+ my ($sym) = gensym;
+ my $cmd = WIN32 ?
+ "$Cpp->{cppstdin} $Defines $addincludes $Cpp->{cppflags} $filename |" :
+ "echo '\#include \"$filename\"' | $Cpp->{cppstdin} $Defines $addincludes $Cpp->{cppflags} $Cpp->{cppminus} | grep -v '^#' |";
+ #my $cmd = "echo '\#include <$filename>' | $Cpp->{cppstdin} $Defines $addincludes $Cpp->{cppflags} $Cpp->{cppminus} |";
+
+ (open($sym, $cmd) or die "Cannot open pipe from `$cmd': $!")
+ and bless $sym => $class;
+}
+
+sub text {
+ my $class = shift;
+ my $filter = shift;
+ if (defined $filter) {
+ return text_only_from($class, $filter, @_);
+ }
+ my $stream = $class->new(@_);
+ my $oh = select $stream;
+ local $/;
+ select $oh;
+ <$stream>;
+}
+
+sub text_only_from {
+ my $class = shift;
+ my $from = shift || die "Expecting argument in `text_only_from'";
+ my $stream = $class->new(@_);
+ my $on = $from eq $_[0];
+ my $eqregexp = $on ? '\"\"|' : '';
+ my @out;
+ while (<$stream>) {
+ #print;
+
+ $on = /$eqregexp[\"\/]\Q$from\"/ if /^\#/;
+ push @out, $_ if $on;
+ }
+ join '', @out;
+}
+
+sub DESTROY {
+ close($_[0])
+ or die "Cannot close pipe from `$Config::Config{cppstdin}': err $?, $!\n";
+}
+
+# Autoload methods go after __END__, and are processed by the autosplit program.
+# Return to the principal package.
+package ModPerl::CScan;
+
+1;
+__END__
+
+=head1 NAME
+
+ModPerl::CScan - scan C language files for easily recognized constructs.
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+See the C<C::Scan> manpage. This package is just a fork to fix certain
+things that didn't work in the original C<C::Scan>, which is not
+maintained any longer. These fixes required to make it work with the
+Apache 2 source code.
+
+=cut
diff --git a/2_0_13/lib/ModPerl/Code.pm b/2_0_13/lib/ModPerl/Code.pm
new file mode 100644
index 0000000..fa6dfe7
--- /dev/null
+++ b/2_0_13/lib/ModPerl/Code.pm
@@ -0,0 +1,1180 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::Code;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Config;
+use File::Spec::Functions qw(catfile catdir);
+
+use mod_perl2 ();
+use Apache2::Build ();
+
+use Apache::TestConfig ();
+use Apache::TestTrace;
+
+our $VERSION = '0.01';
+our @ISA = qw(Apache2::Build);
+
+my %handlers = (
+ Process => [qw(ChildInit ChildExit)], #Restart PreConfig
+ Files => [qw(OpenLogs PostConfig)],
+ PerSrv => [qw(PostReadRequest Trans MapToStorage)],
+ PerDir => [qw(HeaderParser
+ Access Authen Authz
+ Type Fixup Response Log Cleanup
+ InputFilter OutputFilter)],
+ Connection => [qw(ProcessConnection)],
+ PreConnection => [qw(PreConnection)],
+);
+
+my %hooks = map { $_, canon_lc($_) }
+ map { @{ $handlers{$_} } } keys %handlers;
+
+my %not_ap_hook = map { $_, 1 } qw(child_exit response cleanup
+ output_filter input_filter);
+
+my %not_request_hook = map { $_, 1 } qw(child_init process_connection
+ pre_connection open_logs post_config);
+
+my %hook_proto = (
+ Process => {
+ ret => 'void',
+ args => [{type => 'apr_pool_t', name => 'p'},
+ {type => 'server_rec', name => 's'},
+ {type => 'dummy', name => 'MP_HOOK_VOID'}],
+ },
+ Files => {
+ ret => 'int',
+ args => [{type => 'apr_pool_t', name => 'pconf'},
+ {type => 'apr_pool_t', name => 'plog'},
+ {type => 'apr_pool_t', name => 'ptemp'},
+ {type => 'server_rec', name => 's'},
+ {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}],
+ },
+ PerSrv => {
+ ret => 'int',
+ args => [{type => 'request_rec', name => 'r'},
+ {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}],
+ },
+ Connection => {
+ ret => 'int',
+ args => [{type => 'conn_rec', name => 'c'},
+ {type => 'dummy', name => 'MP_HOOK_RUN_FIRST'}],
+ },
+ PreConnection => {
+ ret => 'int',
+ args => [{type => 'conn_rec', name => 'c'},
+ {type => 'void', name => 'csd'},
+ {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}],
+ },
+);
+
+my %cmd_push = (
+ InputFilter => 'modperl_cmd_push_filter_handlers',
+ OutputFilter => 'modperl_cmd_push_filter_handlers',
+);
+my $cmd_push_default = 'modperl_cmd_push_handlers';
+sub cmd_push {
+ $cmd_push{+shift} || $cmd_push_default;
+}
+
+$hook_proto{PerDir} = $hook_proto{PerSrv};
+
+my $scfg_get = 'MP_dSCFG(parms->server)';
+
+my $dcfg_get = "$scfg_get;\n" .
+ ' modperl_config_dir_t *dcfg = (modperl_config_dir_t *)dummy';
+
+my %directive_proto = (
+ PerSrv => {
+ args => [{type => 'cmd_parms', name => 'parms'},
+ {type => 'void', name => 'dummy'},
+ {type => 'const char', name => 'arg'}],
+ cfg => {get => $scfg_get, name => 'scfg'},
+ scope => 'RSRC_CONF',
+ },
+ PerDir => {
+ args => [{type => 'cmd_parms', name => 'parms'},
+ {type => 'void', name => 'dummy'},
+ {type => 'const char', name => 'arg'}],
+ cfg => {get => $dcfg_get, name => 'dcfg'},
+ scope => 'OR_ALL',
+ },
+);
+
+for my $class (qw(Process Connection PreConnection Files)) {
+ $directive_proto{$class}->{cfg}->{name} = 'scfg';
+ $directive_proto{$class}->{cfg}->{get} = $scfg_get;
+
+ for (qw(args scope)) {
+ $directive_proto{$class}->{$_} = $directive_proto{PerSrv}->{$_};
+ }
+}
+
+while (my ($k,$v) = each %directive_proto) {
+ $directive_proto{$k}->{ret} = 'const char *';
+ my $handlers = join '_', 'handlers', canon_lc($k);
+ $directive_proto{$k}->{handlers} =
+ join '->', $directive_proto{$k}->{cfg}->{name}, $handlers;
+}
+
+#XXX: allow disabling of PerDir hooks on a PerDir basis
+my @hook_flags = sort(map { canon_uc($_) } keys %hooks);
+my @ithread_opts = qw(CLONE PARENT);
+my %flags = (
+ Srv => ['NONE', @ithread_opts, qw(ENABLE AUTOLOAD MERGE_HANDLERS),
+ @hook_flags, 'UNSET','INHERIT_SWITCHES'],
+ Dir => [qw(NONE PARSE_HEADERS SETUP_ENV MERGE_HANDLERS GLOBAL_REQUEST UNSET)],
+ Req => [qw(NONE SET_GLOBAL_REQUEST PARSE_HEADERS SETUP_ENV
+ CLEANUP_REGISTERED PERL_SET_ENV_DIR PERL_SET_ENV_SRV)],
+ Interp => [qw(NONE IN_USE CLONED BASE)],
+ Handler => [qw(NONE PARSED METHOD OBJECT ANON AUTOLOAD DYNAMIC FAKE)],
+);
+
+$flags{DirSeen} = $flags{Dir};
+
+my %flags_options = map { $_,1 } qw(Srv Dir);
+
+my %flags_field = (
+ DirSeen => 'flags->opts_seen',
+ (map { $_, 'flags->opts' } keys %flags_options),
+);
+
+sub new {
+ my $class = shift;
+ bless {
+ handlers => \%handlers,
+ hook_proto => \%hook_proto,
+ directive_proto => \%directive_proto,
+ flags => \%flags,
+ path => 'src/modules/perl',
+ }, $class;
+}
+
+sub path { shift->{path} }
+
+sub handler_desc {
+ my ($self, $h_add, $c_add) = @_;
+ local $" = ",\n";
+ foreach my $class (sort keys %{ $self->{handler_index_desc} }) {
+ my $h = $self->{handler_index_desc}->{$class};
+ my $func = canon_func('handler', 'desc', $class);
+ my $array = join '_', 'MP', $func;
+ my $proto = "const char *$func(int idx)";
+
+ $$h_add .= "$proto;\n";
+
+ $$c_add .= <<EOF;
+static const char * $array [] = {
+@{ [ map { $_ ? qq( "$_") : ' NULL' } @$h, '' ] }
+};
+
+$proto
+{
+ return $array [idx];
+}
+
+EOF
+ }
+}
+
+sub generate_handler_index {
+ my ($self, $h_fh) = @_;
+
+ my $type = 1;
+
+ foreach my $class (sort keys %{ $self->{handlers} }) {
+ my $handlers = $self->{handlers}->{$class};
+ my $i = 0;
+ my $n = @$handlers;
+ my $handler_type = canon_define('HANDLER_TYPE', $class);
+
+ print $h_fh "\n#define ",
+ canon_define('HANDLER_NUM', $class), " $n\n\n";
+
+ print $h_fh "#define $handler_type $type\n\n";
+
+ $type++;
+
+ for my $name (@$handlers) {
+ my $define = canon_define($name, 'handler');
+ $self->{handler_index}->{$class}->[$i] = $define;
+ $self->{handler_index_type}->{$class}->[$i] = $handler_type;
+ $self->{handler_index_desc}->{$class}->[$i] = "Perl${name}Handler";
+ print $h_fh "#define $define $i\n";
+ $i++;
+ }
+ }
+}
+
+sub generate_handler_hooks {
+ my ($self, $h_fh, $c_fh) = @_;
+
+ my @register_hooks;
+
+ foreach my $class (sort keys %{ $self->{hook_proto} }) {
+ my $prototype = $self->{hook_proto}->{$class};
+ my $callback = canon_func('callback', $class);
+ my $return = $prototype->{ret} eq 'void' ? '' : 'return';
+ my $i = -1;
+
+ for my $handler (@{ $self->{handlers}{$class} }) {
+ my $name = canon_func($handler, 'handler');
+ $i++;
+
+ if (my $hook = $hooks{$handler}) {
+ next if $not_ap_hook{$hook};
+
+ my $order = $not_request_hook{$hook} ? 'APR_HOOK_FIRST'
+ : 'APR_HOOK_REALLY_FIRST';
+
+ push @register_hooks,
+ " ap_hook_$hook($name, NULL, NULL, $order);";
+ }
+
+ my ($protostr, $pass) = canon_proto($prototype, $name);
+ my $ix = $self->{handler_index}->{$class}->[$i];
+
+ if ($callback =~ m/modperl_callback_per_(dir|srv)/) {
+ if ($ix =~ m/AUTH|TYPE|TRANS|MAP/) {
+ $pass =~ s/MP_HOOK_RUN_ALL/MP_HOOK_RUN_FIRST/;
+ }
+ }
+
+ print $h_fh "\n$protostr;\n";
+
+ print $c_fh <<EOF;
+$protostr
+{
+ $return $callback($ix, $pass);
+}
+
+EOF
+ }
+ }
+
+ local $" = "\n";
+ my $hooks_proto = 'void modperl_register_handler_hooks(void)';
+ my $h_add = "$hooks_proto;\n";
+ my $c_add = "$hooks_proto {\n@register_hooks\n}\n";
+
+ $self->handler_desc(\$h_add, \$c_add);
+
+ return ($h_add, $c_add);
+}
+
+sub generate_handler_find {
+ my ($self, $h_fh, $c_fh) = @_;
+
+ my $proto = 'int modperl_handler_lookup(const char *name, int *type)';
+ my (%ix, %switch);
+
+ print $h_fh "$proto;\n";
+
+ print $c_fh <<EOF;
+$proto
+{
+ if (*name == 'P' && strnEQ(name, "Perl", 4)) {
+ name += 4;
+ }
+
+ switch (*name) {
+EOF
+
+ foreach my $class (sort keys %{ $self->{handlers} }) {
+ my $handlers = $self->{handlers}->{$class};
+ my $i = 0;
+
+ for my $name (@$handlers) {
+ $name =~ /^([A-Z])/;
+ push @{ $switch{$1} }, $name;
+ $ix{$name}->{name} = $self->{handler_index}->{$class}->[$i];
+ $ix{$name}->{type} = $self->{handler_index_type}->{$class}->[$i++];
+ }
+ }
+
+ for my $key (sort keys %switch) {
+ my $names = $switch{$key};
+ print $c_fh " case '$key':\n";
+
+ #support $r->push_handlers(PerlHandler => ...)
+ if ($key eq 'H') {
+ print $c_fh <<EOF;
+ if (strEQ(name, "Handler")) {
+ *type = $ix{'Response'}->{type};
+ return $ix{'Response'}->{name};
+ }
+EOF
+ }
+
+ for my $name (@$names) {
+ my $n = length($name);
+ print $c_fh <<EOF;
+ if (strnEQ(name, "$name", $n)) {
+ *type = $ix{$name}->{type};
+ return $ix{$name}->{name};
+ }
+EOF
+ }
+ }
+
+ print $c_fh " };\n return -1;\n}\n";
+
+ return ("", "");
+}
+
+sub generate_handler_directives {
+ my ($self, $h_fh, $c_fh) = @_;
+
+ my @cmd_entries;
+
+ foreach my $class (sort keys %{ $self->{handlers} }) {
+ my $handlers = $self->{handlers}->{$class};
+ my $prototype = $self->{directive_proto}->{$class};
+ my $i = 0;
+
+ for my $h (@$handlers) {
+ my $h_name = join $h, qw(Perl Handler);
+ my $name = canon_func('cmd', $h, 'handlers');
+ my $cmd_name = canon_define('cmd', $h, 'entry');
+ my $protostr = canon_proto($prototype, $name);
+ my $flag = 'MpSrv' . canon_uc($h);
+ my $ix = $self->{handler_index}->{$class}->[$i++];
+ my $av = "$prototype->{handlers} [$ix]";
+ my $cmd_push = cmd_push($h);
+
+ print $h_fh "$protostr;\n";
+
+ push @cmd_entries, $cmd_name;
+
+ print $h_fh <<EOF;
+
+#define $cmd_name \\
+AP_INIT_ITERATE("$h_name", $name, NULL, \\
+ $prototype->{scope}, "Subroutine name")
+
+EOF
+ print $c_fh <<EOF;
+
+$protostr
+{
+ $prototype->{cfg}->{get};
+ if (!MpSrvENABLE(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "Perl is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+ if (!$flag(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "$h_name is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+ MP_TRACE_d(MP_FUNC, "push \@%s, %s", parms->cmd->name, arg);
+ return $cmd_push(&($av), arg, parms->pool);
+}
+EOF
+ }
+ }
+
+ my $h_add = '#define MP_CMD_ENTRIES \\' . "\n" . join ', \\'."\n", @cmd_entries;
+
+ return ($h_add, "");
+}
+
+sub generate_flags {
+ my ($self, $h_fh, $c_fh) = @_;
+
+ my $n = 1;
+
+ (my $dlsrc = uc $Config{dlsrc}) =~ s/\.xs$//i;
+
+ print $h_fh "\n#define MP_SYS_$dlsrc 1\n";
+
+ foreach my $class (sort keys %{ $self->{flags} }) {
+ my $opts = $self->{flags}->{$class};
+ my @lookup = ();
+ my %lookup = ();
+ my $lookup_proto = "";
+ my %dumper;
+ if ($flags_options{$class}) {
+ $lookup_proto = join canon_func('flags', 'lookup', $class),
+ 'U32 ', '(const char *str)';
+ push @lookup, "$lookup_proto {";
+ }
+
+ my $flags = join $class, qw(Mp FLAGS);
+ my $field = $flags_field{$class} || 'flags';
+
+ print $h_fh "\n#define $flags(p) (p)->$field\n";
+
+ $class = "Mp$class";
+ print $h_fh "\n#define ${class}Type $n\n";
+ $n++;
+
+ my $i = 0;
+ my $max_len = 0;
+ for my $f (@$opts) {
+ my $x = sprintf "0x%08x", $i;
+ my $flag = "${class}_f_$f";
+ my $cmd = $class . $f;
+ my $name = canon_name($f);
+ $lookup{$name} = $flag;
+ $max_len = length $name if $max_len < length $name;
+ print $h_fh <<EOF;
+
+/* $f */
+#define $flag $x
+#define $cmd(p) ($flags(p) & $flag)
+#define ${cmd}_On(p) ($flags(p) |= $flag)
+#define ${cmd}_Off(p) ($flags(p) &= ~$flag)
+
+EOF
+ $dumper{$name} =
+ qq{modperl_trace(NULL, " $name %s", \\
+ ($flags(p) & $x) ? "On " : "Off");};
+
+ $i += $i || 1;
+ }
+ if (@lookup) {
+ my $indent1 = " " x 4;
+ my $indent2 = " " x 8;
+ my %switch = ();
+ for (sort keys %lookup) {
+ if (/^(\w)/) {
+ my $gap = " " x ($max_len - length $_);
+ push @{ $switch{$1} },
+ qq{if (strEQ(str, "$_"))$gap return $lookup{$_};};
+ }
+ }
+
+ push @lookup, '', $indent1 . "switch (*str) {";
+ for (sort keys %switch) {
+ push @lookup, $indent1 . " case '$_':";
+ push @lookup, map { $indent2 . $_ } @{ $switch{$_} };
+ }
+ push @lookup, map { $indent1 . $_ } ("}\n", "return -1;\n}\n\n");
+
+ print $c_fh join "\n", @lookup;
+ print $h_fh "$lookup_proto;\n";
+ }
+
+ delete $dumper{None}; #NONE
+ print $h_fh join ' \\'."\n",
+ "#define ${class}_dump_flags(p, str)",
+ qq{modperl_trace(NULL, "$class flags dump (%s):", str);},
+ map $dumper{$_}, sort keys %dumper;
+ }
+
+ print $h_fh "\n#define MpSrvHOOKS_ALL_On(p) MpSrvFLAGS(p) |= (",
+ (join '|', map { 'MpSrv_f_' . $_ } @hook_flags), ")\n";
+
+ print $h_fh "\n#define MpSrvOPT_ITHREAD_ONLY(o) \\\n",
+ (join ' || ', map("(o == MpSrv_f_$_)", @ithread_opts)), "\n";
+
+ ();
+}
+
+my %trace = (
+ 'a' => 'Apache API interaction',
+ 'c' => 'configuration for directive handlers',
+ 'd' => 'directive processing',
+ 'e' => 'environment variables',
+ 'f' => 'filters',
+ 'g' => 'globals management',
+ 'h' => 'handlers',
+ 'i' => 'interpreter pool management',
+ 'm' => 'memory allocations',
+ 'o' => 'I/O',
+ 'r' => 'Perl runtime interaction',
+ 's' => 'Perl sections',
+ 't' => 'benchmark-ish timings',
+);
+
+sub generate_trace {
+ my ($self, $h_fh) = @_;
+
+ my $v = $self->{build}->{VERSION};
+ my $api_v = $self->{build}->{API_VERSION};
+
+ print $h_fh qq(#define MP_VERSION_STRING "mod_perl/$v"\n);
+
+ # this needs to be a string, not an int, because of the
+ # macro definition. patches welcome.
+ print $h_fh qq(#define MP_API_VERSION "$api_v"\n);
+
+ my $i = 1;
+ my @trace = sort keys %trace;
+ my $opts = join '', @trace;
+ my $tl = "MP_debug_level";
+
+ print $h_fh <<EOF;
+#define MP_TRACE_OPTS "$opts"
+
+#ifdef MP_TRACE
+#define MP_TRACE_any if ($tl) modperl_trace
+#define MP_TRACE_any_do(exp) if ($tl) { \\
+exp; \\
+}
+#else
+#define MP_TRACE_any if (0) modperl_trace
+#define MP_TRACE_any_do(exp)
+#endif
+
+EOF
+
+ my @dumper;
+ for my $type (sort @trace) {
+ my $define = "#define MP_TRACE_$type";
+ my $define_do = join '_', $define, 'do';
+
+ print $h_fh <<EOF;
+#ifdef MP_TRACE
+$define if ($tl & $i) modperl_trace
+$define_do(exp) if ($tl & $i) { \\
+exp; \\
+}
+#else
+$define if (0) modperl_trace
+$define_do(exp)
+#endif
+EOF
+ push @dumper,
+ qq{modperl_trace(NULL, " $type %s ($trace{$type})", ($tl & $i) ? "On " : "Off");};
+ $i += $i;
+ }
+
+ print $h_fh join ' \\'."\n",
+ '#define MP_TRACE_dump_flags()',
+ qq{modperl_trace(NULL, "mod_perl trace flags dump:");},
+ @dumper;
+
+ ();
+}
+
+sub generate_largefiles {
+ my ($self, $h_fh) = @_;
+
+ my $flags = $self->perl_config('ccflags_uselargefiles');
+
+ return unless $flags;
+
+ for my $flag (split /\s+/, $flags) {
+ next if $flag =~ /^-/; # skip -foo flags
+ my ($name, $val) = split '=', $flag;
+ $val ||= '';
+ $name =~ s/^-D//;
+ print $h_fh "#define $name $val\n";
+ }
+}
+
+sub ins_underscore {
+ $_[0] =~ s/([a-z])([A-Z])/$1_$2/g;
+ $_[0] =~ s/::/_/g;
+}
+
+sub canon_uc {
+ my $s = shift;
+ ins_underscore($s);
+ uc $s;
+}
+
+sub canon_lc {
+ my $s = shift;
+ ins_underscore($s);
+ lc $s;
+}
+
+sub canon_func {
+ join '_', 'modperl', map { canon_lc($_) } @_;
+}
+
+sub canon_name {
+ local $_ = shift;
+ s/([A-Z]+)/ucfirst(lc($1))/ge;
+ s/_//g;
+ $_;
+}
+
+sub canon_define {
+ join '_', 'MP', map { canon_uc($_) } @_;
+}
+
+sub canon_args {
+ my $args = shift->{args};
+ my @pass = map { $_->{name} } @$args;
+ my @in;
+ foreach my $href (@$args) {
+ push @in, "$href->{type} *$href->{name}"
+ unless $href->{type} eq 'dummy';
+ }
+ return wantarray ? (\@in, \@pass) : \@in;
+}
+
+sub canon_proto {
+ my ($prototype, $name) = @_;
+ my ($in,$pass) = canon_args($prototype);
+
+ local $" = ', ';
+
+ my $p = "$prototype->{ret} $name(@$in)";
+ $p =~ s/\* /*/;
+ return wantarray ? ($p, "@$pass") : $p;
+}
+
+my %sources = (
+ generate_handler_index => {h => 'modperl_hooks.h'},
+ generate_handler_hooks => {h => 'modperl_hooks.h',
+ c => 'modperl_hooks.c'},
+ generate_handler_directives => {h => 'modperl_directives.h',
+ c => 'modperl_directives.c'},
+ generate_handler_find => {h => 'modperl_hooks.h',
+ c => 'modperl_hooks.c'},
+ generate_flags => {h => 'modperl_flags.h',
+ c => 'modperl_flags.c'},
+ generate_trace => {h => 'modperl_trace.h'},
+ generate_largefiles => {h => 'modperl_largefiles.h'},
+ generate_constants => {h => 'modperl_constants.h',
+ c => 'modperl_constants.c'},
+ generate_exports => {c => 'modperl_exports.c'},
+);
+
+my @c_src_names = qw(interp tipool log config cmd options callback handler
+ gtop util io io_apache filter bucket mgv pcw global env
+ cgi perl perl_global perl_pp sys module svptr_table
+ const constants apache_compat error debug
+ common_util common_log);
+my @h_src_names = qw(perl_unembed);
+my @g_c_names = map { "modperl_$_" } qw(hooks directives flags xsinit exports);
+my @c_names = ('mod_perl', (map "modperl_$_", @c_src_names));
+sub c_files { [map { "$_.c" } @c_names, @g_c_names] }
+sub o_files { [map { "$_.o" } @c_names, @g_c_names] }
+sub o_pic_files { [map { "$_.lo" } @c_names, @g_c_names] }
+
+my @g_h_names = map { "modperl_$_" } qw(hooks directives flags trace
+ largefiles);
+my @h_names = (@c_names, map { "modperl_$_" } @h_src_names,
+ qw(types time apache_includes perl_includes apr_includes
+ apr_compat common_includes common_types));
+sub h_files { [map { "$_.h" } @h_names, @g_h_names] }
+
+sub clean_files {
+ my @c_names = @g_c_names;
+ my @h_names = @g_h_names;
+
+ for (\@c_names, \@h_names) {
+ push @$_, 'modperl_constants';
+ }
+
+ [(map { "$_.c" } @c_names), (map { "$_.h" } @h_names)];
+}
+
+sub classname {
+ my $self = shift || __PACKAGE__;
+ ref($self) || $self;
+}
+
+sub noedit_warning_c {
+ my $class = classname(shift);
+
+ my $v = join '/', $class, $class->VERSION;
+ my $trace = Apache::TestConfig::calls_trace();
+ $trace =~ s/^/ * /mg;
+ return <<EOF;
+
+/*
+ * *********** WARNING **************
+ * This file generated by $v
+ * Any changes made here will be lost
+ * ***********************************
+$trace */
+
+EOF
+}
+
+#this is named hash after the `#' character
+#rather than named perl, since #comments are used
+#non-Perl files, e.g. Makefile, typemap, etc.
+sub noedit_warning_hash {
+ my $class = classname(shift);
+
+ (my $warning = noedit_warning_c($class)) =~ s/^/\# /mg;
+ return $warning;
+}
+
+sub init_file {
+ my ($self, $name) = @_;
+
+ return unless $name;
+ return if $self->{init_files}->{$name}++;
+
+ my (@preamble);
+ if ($name =~ /\.h$/) {
+ (my $d = uc $name) =~ s/\./_/;
+ push @preamble, "#ifndef $d\n#define $d\n";
+ push @{ $self->{postamble}->{$name} }, "\n#endif /* $d */\n";
+ }
+ elsif ($name =~ /\.c/) {
+ push @preamble, qq{\#include "mod_perl.h"\n\n};
+ }
+
+ my $file = "$self->{path}/$name";
+ debug "generating...$file";
+ unlink $file;
+ open my $fh, '>>', $file or die "open $file: $!";
+ print $fh @preamble, noedit_warning_c();
+
+ $self->{fh}->{$name} = $fh;
+}
+
+sub fh {
+ my ($self, $name) = @_;
+ return unless $name;
+ $self->{fh}->{$name};
+}
+
+sub postamble {
+ my $self = shift;
+ for my $name (sort keys %{ $self->{fh} }) {
+ next unless my $av = $self->{postamble}->{$name};
+ print { $self->fh($name) } @$av;
+ }
+}
+
+sub generate {
+ my ($self, $build) = @_;
+
+ $self->{build} = $build;
+
+ for my $s (values %sources) {
+ for (qw(h c)) {
+ $self->init_file($s->{$_});
+ }
+ }
+
+ for my $method (reverse sort keys %sources) {
+ my ($h_fh, $c_fh) = map {
+ $self->fh($sources{$method}->{$_});
+ } qw(h c);
+ my ($h_add, $c_add) = $self->$method($h_fh, $c_fh);
+ if ($h_add) {
+ print $h_fh $h_add;
+ }
+ if ($c_add) {
+ print $c_fh $c_add;
+ }
+ debug "$method...done";
+ }
+
+ $self->postamble;
+
+ my $xsinit = "$self->{path}/modperl_xsinit.c";
+ debug "generating...$xsinit";
+
+ # There's a possibility that $Config{static_ext} may contain spaces
+ # and ExtUtils::Embed::xsinit won't handle the situation right. In
+ # this case we'll get buggy "boot_" statements in modperl_xsinit.c.
+ # Fix this by cleaning the @Extensions array.
+
+ # Loads @Extensions if not loaded
+ ExtUtils::Embed::static_ext();
+
+ @ExtUtils::Embed::Extensions = grep{$_} @ExtUtils::Embed::Extensions;
+
+ #create bootstrap method for static xs modules
+ my $static_xs = [sort keys %{ $build->{XS} }];
+ ExtUtils::Embed::xsinit($xsinit, 1, $static_xs);
+
+ #$self->generate_constants_pod();
+}
+
+my $constant_prefixes = join '|', qw{APR? MODPERL_RC};
+
+sub generate_constants {
+ my ($self, $h_fh, $c_fh) = @_;
+
+ require Apache2::ConstantsTable;
+
+ print $c_fh qq{\#include "modperl_const.h"\n};
+ print $h_fh "#define MP_ENOCONST -3\n\n";
+
+ generate_constants_lookup($h_fh, $c_fh);
+ generate_constants_group_lookup($h_fh, $c_fh);
+}
+
+my %shortcuts = (
+ NOT_FOUND => 'HTTP_NOT_FOUND',
+ FORBIDDEN => 'HTTP_FORBIDDEN',
+ AUTH_REQUIRED => 'HTTP_UNAUTHORIZED',
+ SERVER_ERROR => 'HTTP_INTERNAL_SERVER_ERROR',
+ REDIRECT => 'HTTP_MOVED_TEMPORARILY',
+);
+
+#backwards compat with older httpd/apr
+#XXX: remove once we require newer httpd/apr
+my %ifdef = map { $_, 1 }
+ qw(APLOG_TOCLIENT APR_LIMIT_NOFILE), # added in ???
+ qw(AP_MPMQ_STARTING AP_MPMQ_RUNNING AP_MPMQ_STOPPING
+ AP_MPMQ_MPM_STATE), # added in 2.0.49
+ qw(APR_FPROT_USETID APR_FPROT_GSETID
+ APR_FPROT_WSTICKY APR_FOPEN_LARGEFILE), # added in 2.0.50?
+ qw(OPT_INCNOEXEC OPT_INC_WITH_EXEC); # added/removed in 2.4
+
+sub constants_ifdef {
+ my $name = shift;
+
+ if ($ifdef{$name}) {
+ return ("#ifdef $name\n", "#endif /* $name */\n");
+ }
+
+ ("", "");
+}
+
+sub constants_lookup_code {
+ my ($h_fh, $c_fh, $constants, $class) = @_;
+
+ my (%switch, %alias);
+
+ %alias = %shortcuts;
+
+ my $postfix = canon_lc(lc $class);
+ my $package = $class . '::';
+ my $package_len = length $package;
+ my ($first_let) = $class =~ /^(\w)/;
+
+ my $func = canon_func(qw(constants lookup), $postfix);
+ my $proto = "SV \*$func(pTHX_ const char *name)";
+
+ print $h_fh "$proto;\n";
+
+ print $c_fh <<EOF;
+
+$proto
+{
+ if (*name == '$first_let' && strnEQ(name, "$package", $package_len)) {
+ name += $package_len;
+ }
+
+ switch (*name) {
+EOF
+
+ for (@$constants) {
+ if (s/^($constant_prefixes)(_)?//o) {
+ $alias{$_} = join $2 || "", $1, $_;
+ }
+ else {
+ $alias{$_} ||= $_;
+ }
+ next unless /^([A-Z])/;
+ push @{ $switch{$1} }, $_;
+ }
+
+ for my $key (sort keys %switch) {
+ my $names = $switch{$key};
+ print $c_fh " case '$key':\n";
+
+ for my $name (@$names) {
+ my @ifdef = constants_ifdef($alias{$name});
+ print $c_fh <<EOF;
+$ifdef[0]
+ if (strEQ(name, "$name")) {
+EOF
+
+ if ($name eq 'DECLINE_CMD' ||
+ $name eq 'DIR_MAGIC_TYPE' ||
+ $name eq 'CRLF' ||
+ $name eq 'AUTHN_PROVIDER_GROUP' ||
+ $name eq 'AUTHZ_PROVIDER_GROUP' ||
+ $name eq 'AUTHN_PROVIDER_VERSION' ||
+ $name eq 'AUTHZ_PROVIDER_VERSION' ||
+ $name eq 'AUTHN_DEFAULT_PROVIDER' ||
+ $name eq 'AUTHN_PROVIDER_NAME_NOTE' ||
+ $name eq 'AUTHZ_PROVIDER_NAME_NOTE' ||
+ $name eq 'AUTHN_PREFIX' ||
+ $name eq 'AUTHZ_PREFIX' ||
+ $name eq 'CRLF_ASCII') {
+ print $c_fh <<EOF;
+ return newSVpv($alias{$name}, 0);
+EOF
+ }
+ else {
+ print $c_fh <<EOF;
+ return newSViv($alias{$name});
+EOF
+ }
+
+ print $c_fh <<EOF;
+ }
+$ifdef[1]
+EOF
+ }
+ print $c_fh " break;\n";
+ }
+
+ print $c_fh <<EOF
+ };
+ Perl_croak(aTHX_ "unknown $class\:: constant %s", name);
+ return newSViv(MP_ENOCONST);
+}
+EOF
+}
+
+sub generate_constants_lookup {
+ my ($h_fh, $c_fh) = @_;
+
+ foreach my $class (sort keys %$Apache2::ConstantsTable) {
+ my $groups = $Apache2::ConstantsTable->{$class};
+ my $constants = [sort map { @$_ } values %$groups];
+
+ constants_lookup_code($h_fh, $c_fh, $constants, $class);
+ }
+}
+
+sub generate_constants_group_lookup {
+ my ($h_fh, $c_fh) = @_;
+
+ foreach my $class (sort keys %$Apache2::ConstantsTable) {
+ my $groups = $Apache2::ConstantsTable->{$class};
+ constants_group_lookup_code($h_fh, $c_fh, $class, $groups);
+ }
+}
+
+sub constants_group_lookup_code {
+ my ($h_fh, $c_fh, $class, $groups) = @_;
+ my @tags;
+ my @code;
+
+ $class = canon_lc(lc $class);
+ foreach my $group (sort keys %$groups) {
+ my $constants = $groups->{$group};
+ push @tags, $group;
+ my $name = join '_', 'MP_constants', $class, $group;
+ print $c_fh "\nstatic const char *$name [] = { \n",
+ (map {
+ my @ifdef = constants_ifdef($_);
+ s/^($constant_prefixes)_?//o;
+ qq($ifdef[0] "$_",\n$ifdef[1])
+ } @$constants), " NULL,\n};\n";
+ }
+
+ my %switch;
+ for (@tags) {
+ next unless /^([A-Z])/i;
+ push @{ $switch{$1} }, $_;
+ }
+
+ my $func = canon_func(qw(constants group lookup), $class);
+
+ my $proto = "const char **$func(const char *name)";
+
+ print $h_fh "$proto;\n";
+ print $c_fh "\n$proto\n{\n", " switch (*name) {\n";
+
+ for my $key (sort keys %switch) {
+ my $val = $switch{$key};
+ print $c_fh "\tcase '$key':\n";
+ for my $group (@$val) {
+ my $name = join '_', 'MP_constants', $class, $group;
+ print $c_fh qq|\tif(strEQ("$group", name))\n\t return $name;\n|;
+ }
+ print $c_fh " break;\n";
+ }
+
+ print $c_fh <<EOF;
+ };
+ Perl_croak_nocontext("unknown $class\:: group `%s'", name);
+ return NULL;
+}
+EOF
+}
+
+my %seen_const = ();
+# generates APR::Const and Apache2::Const manpages in ./tmp/
+sub generate_constants_pod {
+ my ($self) = @_;
+
+ my %data = ();
+ generate_constants_group_lookup_doc(\%data);
+ generate_constants_lookup_doc(\%data);
+
+ # XXX: may be dump %data into ModPerl::MethodLookup and provide an
+ # easy api to map const groups to constants and vice versa
+
+ require File::Path;
+ my $file = "Const.pod";
+ for my $class (sort keys %data) {
+ my $path = catdir "tmp", $class;
+ File::Path::mkpath($path, 0, 0755);
+ my $filepath = catfile $path, $file;
+ open my $fh, ">$filepath" or die "Can't open $filepath: $!\n";
+
+ print $fh <<"EOF";
+=head1 NAME
+
+$class\::Const - Perl Interface for $class Constants
+
+=head1 SYNOPSIS
+
+=head1 CONSTANTS
+
+EOF
+
+ my $groups = $data{$class};
+ for my $group (sort keys %$groups) {
+ print $fh <<"EOF";
+
+
+
+=head2 C<:$group>
+
+ use $class\::Const -compile qw(:$group);
+
+The C<:$group> group is for XXX constants.
+
+EOF
+
+ for my $const (sort @{ $groups->{$group} }) {
+ print $fh "=head3 C<$class\::$const>\n\n\n";
+ }
+ }
+
+ print $fh "=cut\n";
+ }
+}
+
+sub generate_constants_lookup_doc {
+ my ($data) = @_;
+
+ foreach my $class (sort keys %$Apache2::ConstantsTable) {
+ my $groups = $Apache2::ConstantsTable->{$class};
+ my $constants = [sort map { @$_ } values %$groups];
+
+ constants_lookup_code_doc($constants, $class, $data);
+ }
+}
+
+sub generate_constants_group_lookup_doc {
+ my ($data) = @_;
+
+ foreach my $class (sort keys %$Apache2::ConstantsTable) {
+ my $groups = $Apache2::ConstantsTable->{$class};
+ constants_group_lookup_code_doc($class, $groups, $data);
+ }
+}
+
+sub constants_group_lookup_code_doc {
+ my ($class, $groups, $data) = @_;
+ my @tags;
+ my @code;
+
+ while (my ($group, $constants) = each %$groups) {
+ $data->{$class}{$group} = [
+ map {
+ my @ifdef = constants_ifdef($_);
+ s/^($constant_prefixes)_?//o;
+ $seen_const{$class}{$_}++;
+ $_;
+ } @$constants
+ ];
+ }
+}
+
+sub constants_lookup_code_doc {
+ my ($constants, $class, $data) = @_;
+
+ my (%switch, %alias);
+
+ %alias = %shortcuts;
+
+ my $postfix = lc $class;
+ my $package = $class . '::';
+ my $package_len = length $package;
+
+ my $func = canon_func(qw(constants lookup), $postfix);
+
+ for (@$constants) {
+ if (s/^($constant_prefixes)(_)?//o) {
+ $alias{$_} = join $2 || "", $1, $_;
+ }
+ else {
+ $alias{$_} ||= $_;
+ }
+ next unless /^([A-Z])/;
+ push @{ $switch{$1} }, $_;
+ }
+
+ for my $key (sort keys %switch) {
+ my $names = $switch{$key};
+ for my $name (@$names) {
+ my @ifdef = constants_ifdef($alias{$name});
+ push @{ $data->{$class}{other} }, $name
+ unless $seen_const{$class}{$name}
+ }
+ }
+}
+
+sub generate_exports {
+ my ($self, $c_fh) = @_;
+ require ModPerl::WrapXS;
+ ModPerl::WrapXS->generate_exports($c_fh);
+}
+
+# src/modules/perl/*.c files needed to build APR/APR::* outside
+# of mod_perl.so
+sub src_apr_ext {
+ return map { "modperl_$_" } (qw(error bucket),
+ map { "common_$_" } qw(util log));
+}
+
+1;
+__END__
+
+=head1 NAME
+
+ModPerl::Code - Generate mod_perl glue code
+
+=head1 SYNOPSIS
+
+ use ModPerl::Code ();
+ my $code = ModPerl::Code->new;
+ $code->generate;
+
+=head1 DESCRIPTION
+
+This module provides functionality for generating mod_perl glue code.
+Reason this code is generated rather than written by hand include:
+
+=over 4
+
+=item consistency
+
+=item thin and clean glue code
+
+=item enable/disable features (without #ifdefs)
+
+=item adapt to changes in Apache
+
+=item experiment with different approaches to gluing
+
+=back
+
+=head1 AUTHOR
+
+Doug MacEachern
+
+=cut
diff --git a/2_0_13/lib/ModPerl/Config.pm b/2_0_13/lib/ModPerl/Config.pm
new file mode 100644
index 0000000..89b0f51
--- /dev/null
+++ b/2_0_13/lib/ModPerl/Config.pm
@@ -0,0 +1,98 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::Config;
+
+use strict;
+
+use Apache2::Build ();
+use Apache::TestConfig ();
+use File::Spec ();
+
+use constant WIN32 => Apache2::Build::WIN32;
+
+sub as_string {
+ my $build = Apache2::Build->build_config;
+
+ my $cfg = '';
+
+ $cfg .= "*** mod_perl version $mod_perl::VERSION\n\n";;
+
+ my $file = File::Spec->rel2abs($INC{'Apache2/BuildConfig.pm'});
+ $cfg .= "*** using $file\n\n";
+
+ # the widest key length
+ my $max_len = 0;
+ for (map {length} grep /^MP_/, keys %$build) {
+ $max_len = $_ if $_ > $max_len;
+ }
+
+ # mod_perl opts
+ $cfg .= "*** Makefile.PL options:\n";
+ $cfg .= join '',
+ map {sprintf " %-${max_len}s => %s\n", $_, $build->{$_}}
+ grep /^MP_/, sort keys %$build;
+
+ my $command = '';
+
+ # httpd opts
+ my $test_config = Apache::TestConfig->new({thaw=>1});
+
+ if (my $httpd = $test_config->{vars}->{httpd}) {
+ $command = "$httpd -V";
+ $cfg .= "\n\n*** $command\n";
+ $cfg .= qx{$command};
+
+ $cfg .= Apache::TestConfig::ldd_as_string($httpd);
+ }
+ else {
+ $cfg .= "\n\n*** The httpd binary was not found\n";
+ }
+
+ # apr
+ $cfg .= "\n\n*** (apr|apu)-config linking info\n\n";
+ my @apru_link_flags = $build->apru_link_flags;
+ if (@apru_link_flags) {
+ my $libs = join "\n", @apru_link_flags;
+ $cfg .= "$libs\n\n";
+ }
+ else {
+ $cfg .= "(apr|apu)-config scripts were not found\n\n";
+ }
+
+ # perl opts
+ my $perl = $build->{MODPERL_PERLPATH};
+ $command = "$perl -V";
+ $cfg .= "\n\n*** $command\n";
+ $cfg .= qx{$command};
+
+ return $cfg;
+
+}
+
+1;
+__END__
+
+=pod
+
+=head1 NAME
+
+ModPerl::Config - Functions to retrieve mod_perl specific env information.
+
+=head1 DESCRIPTION
+
+=cut
+
diff --git a/2_0_13/lib/ModPerl/FunctionMap.pm b/2_0_13/lib/ModPerl/FunctionMap.pm
new file mode 100644
index 0000000..e611132
--- /dev/null
+++ b/2_0_13/lib/ModPerl/FunctionMap.pm
@@ -0,0 +1,216 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::FunctionMap;
+
+use strict;
+use warnings FATAL => 'all';
+use ModPerl::MapUtil qw();
+use ModPerl::ParseSource ();
+
+our @ISA = qw(ModPerl::MapBase);
+
+sub new {
+ my $class = shift;
+ bless {}, $class;
+}
+
+#for adding to function.map
+sub generate {
+ my $self = shift;
+
+ my $missing = $self->check;
+ return unless $missing;
+
+ print " $_\n" for @$missing;
+}
+
+sub disabled { shift->{disabled} }
+
+#look for functions that do not exist in *.map
+sub check {
+ my $self = shift;
+ my $map = $self->get;
+
+ my @missing;
+ my $mp_func = ModPerl::ParseSource->wanted_functions;
+
+ for my $name (map $_->{name}, @{ $self->function_table() }) {
+ next if exists $map->{$name};
+ push @missing, $name unless $name =~ /^($mp_func)/o;
+ }
+
+ return @missing ? \@missing : undef;
+}
+
+#look for functions in *.map that do not exist
+my $special_name = qr{(^DEFINE_|DESTROY$)};
+
+sub check_exists {
+ my $self = shift;
+
+ my %functions = map { $_->{name}, 1 } @{ $self->function_table() };
+ my @missing = ();
+
+ for my $name (keys %{ $self->{map} }) {
+ next if $functions{$name};
+ push @missing, $name unless $name =~ $special_name;
+ }
+
+ return @missing ? \@missing : undef;
+}
+
+my $keywords = join '|', qw(MODULE PACKAGE PREFIX BOOT);
+
+sub guess_prefix {
+ my $entry = shift;
+
+ my ($name, $class) = ($entry->{name}, $entry->{class});
+ my $prefix = "";
+ $name =~ s/^DEFINE_//;
+ $name =~ s/^mpxs_//i;
+
+ (my $modprefix = ($entry->{class} || $entry->{module}) . '_') =~ s/::/__/g;
+ (my $guess = lc $modprefix) =~ s/_+/_/g;
+
+ $guess =~ s/(apache2)_/($1|ap)_{1,2}/;
+
+ if ($name =~ s/^($guess|$modprefix).*/$1/i) {
+ $prefix = $1;
+ }
+ else {
+ if ($name =~ /^(apr?_)/) {
+ $prefix = $1;
+ }
+ }
+
+ #print "GUESS prefix=$guess, name=$entry->{name} -> $prefix\n";
+
+ return $prefix;
+}
+
+sub parse {
+ my ($self, $fh, $map) = @_;
+ my %cur;
+ my $disabled = 0;
+
+ while ($fh->readline) {
+ if (/($keywords)=/o) {
+ $disabled = s/^\W//; #module is disabled
+ my %words = $self->parse_keywords($_);
+
+ if ($words{MODULE}) {
+ %cur = ();
+ }
+
+ if ($words{PACKAGE}) {
+ delete $cur{CLASS};
+ }
+
+ for (keys %words) {
+ $cur{$_} = $words{$_};
+ }
+
+ next;
+ }
+
+ my ($name, $dispatch, $argspec, $alias) = split /\s*\|\s*/;
+ my $return_type;
+
+ if ($name =~ s/^([^:]+)://) {
+ $return_type = $1;
+ $return_type =~ s/\s+$//; # allow: char * :....
+ }
+
+ if ($name =~ s/^(\W)// or not $cur{MODULE} or $disabled) {
+ #notimplemented or cooked by hand
+ die qq[function '$name' appears more than once in xs/maps files]
+ if $map->{$name};
+
+ $map->{$name} = undef;
+ push @{ $self->{disabled}->{ $1 || '!' } }, $name;
+ next;
+ }
+
+ if (my $package = $cur{PACKAGE}) {
+ unless ($package eq 'guess') {
+ $cur{CLASS} = $package;
+ }
+ if ($cur{ISA}) {
+ $self->{isa}->{ $cur{MODULE} }->{$package} = delete $cur{ISA};
+ }
+ if ($cur{BOOT}) {
+ $self->{boot}->{ $cur{MODULE} } = delete $cur{BOOT};
+ }
+ }
+ else {
+ $cur{CLASS} = $cur{MODULE};
+ }
+
+ #XXX: make_prefix() stuff should be here, not ModPerl::WrapXS
+ if ($name =~ /^DEFINE_/ and $cur{CLASS}) {
+ $name =~ s{^(DEFINE_)(.*)}
+ {$1 . ModPerl::WrapXS::make_prefix($2, $cur{CLASS})}e;
+ }
+
+ die qq[function '$name' appears more than once in xs/maps files]
+ if $map->{$name};
+
+ my $entry = $map->{$name} = {
+ name => $alias || $name,
+ dispatch => $dispatch,
+ argspec => $argspec ? [split /\s*,\s*/, $argspec] : "",
+ return_type => $return_type,
+ alias => $alias,
+ };
+
+ for (keys %cur) {
+ $entry->{lc $_} = $cur{$_};
+ }
+
+ #avoid 'use of uninitialized value' warnings
+ $entry->{$_} ||= "" for keys %{ $entry };
+ if ($entry->{dispatch} =~ /_$/) {
+ $entry->{dispatch} .= $name;
+ }
+ }
+}
+
+sub get {
+ my $self = shift;
+
+ $self->{map} ||= $self->parse_map_files;
+}
+
+sub prefixes {
+ my $self = shift;
+ $self = ModPerl::FunctionMap->new unless ref $self;
+
+ my $map = $self->get;
+ my %prefix;
+
+ while (my ($name, $ent) = each %$map) {
+ next unless $ent->{prefix};
+ $prefix{ $ent->{prefix} }++;
+ }
+
+ $prefix{$_} = 1 for qw(ap_ apr_); #make sure we get these
+
+ [keys %prefix]
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/ModPerl/MM.pm b/2_0_13/lib/ModPerl/MM.pm
new file mode 100644
index 0000000..597a743
--- /dev/null
+++ b/2_0_13/lib/ModPerl/MM.pm
@@ -0,0 +1,175 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::MM;
+
+use strict;
+use warnings;
+
+use ExtUtils::MakeMaker ();
+use ExtUtils::Install ();
+
+use Cwd ();
+use Carp;
+
+our %PM; #add files to installation
+
+# MM methods that this package overrides
+no strict 'refs';
+my $stash = \%{__PACKAGE__ . '::MY::'};
+my @methods = grep *{$stash->{$_}}{CODE}, keys %$stash;
+my $eu_mm_mv_all_methods_overriden = 0;
+
+use strict 'refs';
+
+sub override_eu_mm_mv_all_methods {
+ my @methods = @_;
+
+ my $orig_sub = \&ExtUtils::MakeMaker::mv_all_methods;
+ no warnings 'redefine';
+ *ExtUtils::MakeMaker::mv_all_methods = sub {
+ # do the normal move
+ $orig_sub->(@_);
+ # for all the overloaded methods mv_all_method installs a stab
+ # eval "package MY; sub $method { shift->SUPER::$method(\@_); }";
+ # therefore we undefine our methods so on the recursive invocation of
+ # Makefile.PL they will be undef, unless defined in Makefile.PL
+ # and my_import will override these methods properly
+ for my $sym (@methods) {
+ my $name = "MY::$sym";
+ undef &$name if defined &$name;
+ }
+ };
+}
+
+sub add_dep {
+ my ($string, $targ, $add) = @_;
+ $$string =~ s/($targ\s+::)/$1 $add/;
+}
+
+sub add_dep_before {
+ my ($string, $targ, $before_targ, $add) = @_;
+ $$string =~ s/($targ\s+::.*?) ($before_targ)/$1 $add $2/;
+}
+
+sub add_dep_after {
+ my ($string, $targ, $after_targ, $add) = @_;
+ $$string =~ s/($targ\s+::.*?$after_targ)/$1 $add/;
+}
+
+my $build;
+
+sub build_config {
+ my $key = shift;
+ require Apache2::Build;
+ $build ||= Apache2::Build->build_config;
+ return $build unless $key;
+ $build->{$key};
+}
+
+#the parent WriteMakefile moves MY:: methods into a different class
+#so alias them each time WriteMakefile is called in a subdir
+
+sub my_import {
+ my $package = shift;
+ no strict 'refs';
+ my $stash = \%{$package . '::MY::'};
+ for my $sym (keys %$stash) {
+ next unless *{$stash->{$sym}}{CODE};
+ my $name = "MY::$sym";
+ # the method is defined in Makefile.PL
+ next if defined &$name;
+ # do the override behind the scenes
+ *$name = *{$stash->{$sym}}{CODE};
+ }
+}
+
+my @default_opts = qw(CCFLAGS LIBS INC OPTIMIZE LDDLFLAGS TYPEMAPS);
+my @default_dlib_opts = qw(OTHERLDFLAGS);
+my @default_macro_opts = ();
+my %opts = (
+ CCFLAGS => sub { $build->{MODPERL_CCOPTS} },
+ LIBS => sub { join ' ', $build->apache_libs, $build->modperl_libs },
+ INC => sub { $build->inc; },
+ OPTIMIZE => sub { $build->perl_config('optimize'); },
+ LDDLFLAGS => sub { $build->perl_config('lddlflags'); },
+ TYPEMAPS => sub { $build->typemaps; },
+ OTHERLDFLAGS => sub { $build->otherldflags; },
+);
+
+sub get_def_opt {
+ my $opt = shift;
+ return $opts{$opt}->() if exists $opts{$opt};
+ # handle cases when Makefile.PL wants an option we don't have a
+ # default for. XXX: some options expect [] rather than scalar.
+ Carp::carp("!!! no default argument defined for argument: $opt");
+ return '';
+}
+
+sub WriteMakefile {
+ my %args = @_;
+
+ # override ExtUtils::MakeMaker::mv_all_methods
+ # can't do that on loading since ModPerl::MM is also use()'d
+ # by ModPerl::BuildMM which itself overrides it
+ unless ($eu_mm_mv_all_methods_overriden) {
+ override_eu_mm_mv_all_methods(@methods);
+ $eu_mm_mv_all_methods_overriden++;
+ }
+
+ $build ||= build_config();
+ my_import(__PACKAGE__);
+
+ # set top-level WriteMakefile's values if weren't set already
+ for my $o (@default_opts) {
+ $args{$o} = get_def_opt($o) unless exists $args{$o}; # already defined
+ }
+
+ # set dynamic_lib-level WriteMakefile's values if weren't set already
+ $args{dynamic_lib} ||= {};
+ my $dlib = $args{dynamic_lib};
+ for my $o (@default_dlib_opts) {
+ $dlib->{$o} = get_def_opt($o) unless exists $dlib->{$o};
+ }
+
+ # set macro-level WriteMakefile's values if weren't set already
+ $args{macro} ||= {};
+ my $macro = $args{macro};
+ for my $o (@default_macro_opts) {
+ $macro->{$o} = get_def_opt($o) unless exists $macro->{$o};
+ }
+
+ ExtUtils::MakeMaker::WriteMakefile(%args);
+}
+
+#### MM overrides ####
+
+sub ModPerl::MM::MY::post_initialize {
+ my $self = shift;
+
+ $build ||= build_config();
+ my $pm = $self->{PM};
+
+ while (my ($k, $v) = each %PM) {
+ if (-e $k) {
+ $pm->{$k} = $v;
+ }
+ }
+
+ '';
+}
+
+1;
diff --git a/2_0_13/lib/ModPerl/Manifest.pm b/2_0_13/lib/ModPerl/Manifest.pm
new file mode 100644
index 0000000..82cbdec
--- /dev/null
+++ b/2_0_13/lib/ModPerl/Manifest.pm
@@ -0,0 +1,128 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::Manifest;
+
+use strict;
+use warnings FATAL => 'all';
+
+use File::Basename;
+use File::Find;
+use Cwd ();
+use Exporter ();
+
+our @EXPORT_OK = qw(mkmanifest);
+
+*import = \&Exporter::import;
+
+#generate a MANIFEST based on CVS/Entries
+#anything to be skipped goes after __DATA__ (MANIFEST.SKIP format)
+#anything else to be added should go here:
+my @add_files = qw{
+ MANIFEST
+ mod_perl.spec
+ Apache-Test/META.yml
+};
+
+sub get_svn_files {
+ my @files;
+
+ my $cwd = Cwd::cwd();
+ my @lines = `svn status -v` ;
+ foreach my $line (@lines) {
+ chomp $line;
+ if ($line =~ /(?:\d+)\s+(?:\d+)\s+(?:\w+)\s+(.*)\s*/) {
+ my $file = $1;
+ if (-e $file && ! -d $file) {
+ $file =~ s{\\}{/}g;
+ push @files, $file;
+ }
+ }
+ }
+
+ # files to add which aren't under svn
+ push @files, qw(lib/ModPerl/DummyVersions.pm lib/ModPerl/MethodLookup.pm);
+
+ return @files;
+}
+
+sub mkmanifest {
+ my @files = (@add_files, get_svn_files());
+
+ my $matches = maniskip();
+ open my $fh, '>', 'MANIFEST' or die "open MANIFEST: $!";
+
+ for my $file (sort @files) {
+ if ($matches->($file)) {
+ warn "skipping $file\n";
+ next;
+ }
+
+ print "$file\n";
+ print $fh "$file\n";
+ }
+
+ close $fh;
+}
+
+#copied from ExtUtils::Manifest
+#uses DATA instead of MANIFEST.SKIP
+sub maniskip {
+ my $matches = sub {0};
+ my @skip;
+
+ while (<DATA>){
+ chomp;
+ next if /^#/;
+ next if /^\s*$/;
+ push @skip, $_;
+ }
+
+ my $sub = "\$matches = "
+ . "sub { my (\$arg)=\@_; return 1 if "
+ . join (" || ", (map {s!/!\\/!g; "\$arg =~ m/$_/o"} @skip), 0)
+ . " }";
+
+ eval $sub;
+
+ $matches;
+}
+
+1;
+__DATA__
+patches/
+#very few will have Chatbot::Eliza installed
+eliza
+# random failures
+t/perl/ithreads.t
+t/perl/ithreads2.t
+t/response/TestPerl/ithreads.pm
+t/response/TestPerl/ithreads_args.pm
+t/response/TestPerl/ithreads_eval.pm
+# broken/out-dated
+t/perl/ithreads3.t
+t/response/TestPerl/ithreads3.pm
+# incomplete
+t/apr-ext/perlio
+# PAUSE breaks if a dist has more than one META.yml. the top-level
+# META.yml already excludes Apache-Test from indexing
+Apache-Test/META.yml
+# exclude Apache-Test/MANIFEST since it confuses the mp2 build (e.g it
+# wants Apache-Test/META.yml which we don't supply, see above)
+Apache-Test/MANIFEST
+
+# this is an internal to developers sub-project
+Apache-Test/Apache-TestItSelf
diff --git a/2_0_13/lib/ModPerl/MapUtil.pm b/2_0_13/lib/ModPerl/MapUtil.pm
new file mode 100644
index 0000000..aa4f3d1
--- /dev/null
+++ b/2_0_13/lib/ModPerl/MapUtil.pm
@@ -0,0 +1,259 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::MapUtil;
+
+use strict;
+use warnings;
+use Exporter ();
+use Apache2::Build ();
+
+our @EXPORT_OK = qw(list_first disabled_reason
+ function_table structure_table
+ xs_glue_dirs);
+
+our @ISA = qw(Exporter);
+
+# the mapping happens in lib/ModPerl/StructureMap.pm: sub parse
+# '<' => 'auto-generated but gives only a read-only access'
+# '&' => 'RDWR accessor to a char* field, supporting undef arg'
+# '$' => 'RONLY accessor, with WRITE accessor before child_init'
+# '%' => like $, but makes sure that for the write accessor the
+# original perl scalar can change or go away w/o affecting
+# the object
+my %disabled_map = (
+ '!' => 'disabled or not yet implemented',
+ '~' => 'implemented but not auto-generated',
+ '-' => 'likely never be available to Perl',
+ '>' => '"private" to apache',
+ '?' => 'unclassified',
+);
+
+my $function_table = [];
+
+sub function_table {
+ return $function_table if @$function_table;
+ my $build = Apache2::Build->new();
+ my $httpd_version = $build->httpd_version;
+ if ($httpd_version lt '2.4.0' || ! -d "xs/tables/current24") {
+ push @INC, "xs/tables/current";
+ }
+ else {
+ push @INC, "xs/tables/current24";
+ }
+ require Apache2::FunctionTable;
+ require ModPerl::FunctionTable;
+ require APR::FunctionTable;
+ @$function_table = (@$Apache2::FunctionTable, @$ModPerl::FunctionTable,
+ @$APR::FunctionTable);
+ $function_table;
+}
+
+my $structure_table = [];
+
+sub structure_table {
+ return $structure_table if @$structure_table;
+ require Apache2::StructureTable;
+ @$structure_table = (@$Apache2::StructureTable);
+ $structure_table;
+}
+
+sub disabled_reason {
+ $disabled_map{+shift} || 'unknown';
+}
+
+sub xs_glue_dirs {
+ Apache2::Build->build_config->mp_xs_glue_dir;
+}
+
+sub list_first (&@) {
+ my $code = shift;
+
+ for (@_) {
+ return $_ if $code->();
+ }
+
+ undef;
+}
+
+package ModPerl::MapBase;
+
+*function_table = \&ModPerl::MapUtil::function_table;
+*structure_table = \&ModPerl::MapUtil::structure_table;
+
+my @condition;
+
+sub readline {
+ my $fh = shift;
+
+ while (<$fh>) {
+ chomp;
+ s/^\s+//; s/\s+$//;
+
+ # this implements
+ # #_if_ cmd
+ # ...
+ # #_else_
+ # #_end_
+ if (/^\s*#\s*_(if|unless|els(?:e|if)|end)_(?:\s(.+))?/) {
+ my ($cmd, $param) = ($1, $2);
+ if (defined $param) {
+ while ($param=~s!\\$!!) {
+ my $l=<$fh>;
+ die "$ModPerl::MapUtil::MapFile($.): unexpected EOF\n"
+ unless defined $l;
+ chomp $l;
+ $param.=$l;
+ }
+ }
+ if ($cmd eq 'if') {
+ unshift @condition,
+ 0+!!eval "#line $. $ModPerl::MapUtil::MapFile\n".$param;
+ die $@ if $@;
+ }
+ elsif ($cmd eq 'elsif') {
+ die "parse error ($ModPerl::MapUtil::MapFile line $.)".
+ " #_elsif_ without #_if_"
+ unless @condition;
+ if ($condition[0] == 0) {
+ $condition[0]+=
+ !!eval "#line $. $ModPerl::MapUtil::MapFile\n".$param;
+ die $@ if $@;
+ } else {
+ $condition[0]++;
+ }
+ }
+ elsif ($cmd eq 'else') {
+ die "parse error ($ModPerl::MapUtil::MapFile line $.)".
+ " #_elsif_ without #_if_"
+ unless @condition;
+ $condition[0]+=1;
+ }
+ elsif ($cmd eq 'unless') {
+ unshift @condition,
+ 0+!eval "#line $. $ModPerl::MapUtil::MapFile\n".$param;
+ die $@ if $@;
+ }
+ elsif ($cmd eq 'end') {
+ shift @condition;
+ }
+ }
+ next if @condition and $condition[0] != 1;
+
+ if (/^\s*#\s*_(eval)_(?:\s(.+))?/) {
+ my ($cmd, $param) = ($1, $2);
+ if (defined $param) {
+ while ($param=~s!\\$!!) {
+ my $l=<$fh>;
+ die "$ModPerl::MapUtil::MapFile($.): unexpected EOF\n"
+ unless defined $l;
+ chomp $l;
+ $param.=$l;
+ }
+ }
+ if ($cmd eq 'eval') {
+ eval "#line $. $ModPerl::MapUtil::MapFile\n".$param;
+ die $@ if $@;
+ }
+ next;
+ }
+
+ s/\s*\#.*//;
+
+ next unless $_;
+
+ if (s:\\$::) {
+ my $cur = $_;
+ $_ = $cur . $fh->readline;
+ return $_;
+ }
+
+ return $_;
+ }
+}
+
+our $MapDir;
+
+my $map_classes = join '|', qw(type structure function);
+
+sub map_files {
+ my $self = shift;
+ my $package = ref($self) || $self;
+
+ my ($wanted) = $package =~ /($map_classes)/io;
+
+ my (@dirs) = (($MapDir || './xs'), ModPerl::MapUtil::xs_glue_dirs());
+
+ my @files;
+
+ for my $dir (map { -d "$_/maps" ? "$_/maps" : $_ } @dirs) {
+ opendir my $dh, $dir or warn "opendir $dir: $!";
+
+ for (readdir $dh) {
+ next unless /\.map$/;
+
+ my $file = "$dir/$_";
+
+ if ($wanted) {
+ next unless $file =~ /$wanted/i;
+ }
+
+ #print "$package => $file\n";
+ push @files, $file;
+ }
+
+ closedir $dh;
+ }
+
+ return @files;
+}
+
+sub parse_keywords {
+ my ($self, $line) = @_;
+ my %words;
+
+ for my $pair (split /\s+/, $line) {
+ my ($key, $val) = split /=/, $pair;
+
+ unless ($key and $val) {
+ die "parse error ($ModPerl::MapUtil::MapFile line $.)";
+ }
+
+ $words{$key} = $val;
+ }
+
+ %words;
+}
+
+sub parse_map_files {
+ my ($self) = @_;
+
+ my $map = {};
+
+ for my $file (map_files($self)) {
+ open my $fh, $file or die "open $file: $!";
+ local $ModPerl::MapUtil::MapFile = $file;
+ bless $fh, __PACKAGE__;
+ @condition=(); # see readline() above
+ $self->parse($fh, $map);
+ close $fh;
+ }
+
+ return $map;
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/ModPerl/ParseSource.pm b/2_0_13/lib/ModPerl/ParseSource.pm
new file mode 100644
index 0000000..4b8ccb7
--- /dev/null
+++ b/2_0_13/lib/ModPerl/ParseSource.pm
@@ -0,0 +1,65 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::ParseSource;
+
+use strict;
+use Config ();
+use Apache2::ParseSource ();
+
+our @ISA = qw(Apache2::ParseSource);
+our $VERSION = '0.01';
+
+sub includes {
+ my $self = shift;
+ my $dirs = $self->SUPER::includes;
+ return [
+ '.', qw(xs src/modules/perl),
+ @$dirs,
+ "$Config::Config{archlibexp}/CORE",
+ ];
+}
+
+sub include_dirs { '.' }
+
+sub find_includes {
+ my $self = shift;
+ my $includes = $self->SUPER::find_includes;
+ #filter/sort
+ my @wanted = grep { /mod_perl\.h/ } @$includes;
+ push @wanted, grep { m:xs/modperl_xs_: } @$includes;
+ push @wanted, grep { m:xs/[AM]: } @$includes;
+ \@wanted;
+}
+
+my $prefixes = join '|', qw(modperl mpxs mp_xs);
+my $prefix_re = qr{^($prefixes)_};
+sub wanted_functions { $prefix_re }
+
+sub write_functions_pm {
+ my $self = shift;
+ my $file = shift || 'FunctionTable.pm';
+ my $name = shift || 'ModPerl::FunctionTable';
+ $self->SUPER::write_functions_pm($file, $name);
+}
+
+for my $method (qw(get_constants get_structs write_structs_pm get_structs)) {
+ no strict 'refs';
+ *$method = sub { die __PACKAGE__ . "->$method not implemented" };
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/ModPerl/StructureMap.pm b/2_0_13/lib/ModPerl/StructureMap.pm
new file mode 100644
index 0000000..2d4c47b
--- /dev/null
+++ b/2_0_13/lib/ModPerl/StructureMap.pm
@@ -0,0 +1,164 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::StructureMap;
+
+use strict;
+use warnings FATAL => 'all';
+use ModPerl::MapUtil qw(structure_table);
+
+our @ISA = qw(ModPerl::MapBase);
+
+sub new {
+ my $class = shift;
+ bless {}, $class;
+}
+
+sub generate {
+ my $self = shift;
+ my $map = $self->get;
+
+ for my $entry (@{ structure_table() }) {
+ my $type = $entry->{type};
+ my $elts = $entry->{elts};
+
+ next unless @$elts;
+ next if $type =~ $self->{IGNORE_RE};
+ next unless grep {
+ not exists $map->{$type}->{ $_->{name} }
+ } @$elts;
+
+ print "<$type>\n";
+ for my $e (@$elts) {
+ print " $e->{name}\n";
+ }
+ print "</$type>\n\n";
+ }
+}
+
+sub disabled { shift->{disabled} }
+
+sub check {
+ my $self = shift;
+ my $map = $self->get;
+
+ my @missing;
+
+ for my $entry (@{ structure_table() }) {
+ my $type = $entry->{type};
+
+ for my $name (map $_->{name}, @{ $entry->{elts} }) {
+ next if exists $map->{$type}->{$name};
+ next if $type =~ $self->{IGNORE_RE};
+ push @missing, "$type.$name";
+ }
+ }
+
+ return @missing ? \@missing : undef;
+}
+
+sub check_exists {
+ my $self = shift;
+
+ my %structures;
+ for my $entry (@{ structure_table() }) {
+ $structures{ $entry->{type} } = { map {
+ $_->{name}, 1
+ } @{ $entry->{elts} } };
+ }
+
+ my @missing;
+
+ while (my ($type, $elts) = each %{ $self->{map} }) {
+ for my $name (keys %$elts) {
+ next if exists $structures{$type}->{$name};
+ push @missing, "$type.$name";
+ }
+ }
+
+ return @missing ? \@missing : undef;
+}
+
+sub parse {
+ my ($self, $fh, $map) = @_;
+
+ my ($disabled, $class);
+ my %cur;
+
+ while ($fh->readline) {
+ if (m:^(\W?)</?([^>]+)>:) {
+ my $args;
+ $disabled = $1;
+ ($class, $args) = split /\s+/, $2, 2;
+
+ %cur = ();
+ if ($args and $args =~ /E=/) {
+ %cur = $self->parse_keywords($args);
+ }
+
+ $self->{MODULES}->{$class} = $cur{MODULE} if $cur{MODULE};
+
+ next;
+ }
+ elsif (s/^(\w+):\s*//) {
+ push @{ $self->{$1} }, split /\s+/;
+ next;
+ }
+
+ if (s/^(\W)\s*// or $disabled) {
+ # < denotes a read-only accessor
+ if ($1) {
+ if ($1 eq '<') {
+ $map->{$class}->{$_} = 'ro';
+ }
+ elsif ($1 eq '&') {
+ $map->{$class}->{$_} = 'rw_char_undef';
+ }
+ elsif ($1 eq '$') {
+ $map->{$class}->{$_} = 'r+w_startup';
+ }
+ elsif ($1 eq '%') {
+ $map->{$class}->{$_} = 'r+w_startup_dup';
+ }
+ }
+ else {
+ $map->{$class}->{$_} = undef;
+ push @{ $self->{disabled}->{ $1 || '!' } }, "$class.$_";
+ }
+
+ }
+ else {
+ $map->{$class}->{$_} = 'rw';
+ }
+ }
+
+ if (my $ignore = $self->{IGNORE}) {
+ $ignore = join '|', @$ignore;
+ $self->{IGNORE_RE} = qr{^($ignore)};
+ }
+ else {
+ $self->{IGNORE_RE} = qr{^$};
+ }
+}
+
+sub get {
+ my $self = shift;
+
+ $self->{map} ||= $self->parse_map_files;
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/ModPerl/TestReport.pm b/2_0_13/lib/ModPerl/TestReport.pm
new file mode 100644
index 0000000..f2b9825
--- /dev/null
+++ b/2_0_13/lib/ModPerl/TestReport.pm
@@ -0,0 +1,104 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::TestReport;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache::TestReportPerl);
+
+use ExtUtils::MakeMaker ();
+
+my @interesting_packages = qw(
+ CGI
+ ExtUtils::MakeMaker
+ Apache2::Request
+ mod_perl2
+ LWP
+ Apache2
+ mod_perl
+);
+
+# we want to see only already installed packages, so skip over
+# modules that are about to be installed
+my @skip_dirs = qw(
+ blib/lib
+ blib/arch
+ lib
+);
+my $skip_dir_str = join '|', map { s|/|[/\\\\]|g; $_ } @skip_dirs;
+my $skip_dir_pat = qr|[/\\]($skip_dir_str)[/\\]*$|;
+
+sub packages {
+
+ my @inc = grep !/$skip_dir_pat/, @INC;
+
+ my %packages = ();
+ my $max_len = 0;
+ for my $package (sort @interesting_packages ) {
+ $max_len = length $package if length $package > $max_len;
+ my $filename = package2filename($package);
+ my @ver = ();
+ for my $dir (@inc) {
+ my $path = "$dir/$filename";
+ if (-e $path) {
+ my $ver = MM->parse_version($path);
+ # two versions could be installed (one under Apache2/)
+ push @{ $packages{$package} }, $ver if $ver;
+ }
+ }
+ }
+
+ my @lines = "*** Packages of interest status:\n";
+
+ for my $package (sort @interesting_packages) {
+ my $vers = exists $packages{$package}
+ ? join ", ", sort @{ $packages{$package} }
+ : "-";
+ push @lines, sprintf "%-${max_len}s: %s", $package, $vers;
+ }
+
+ return join "\n", @lines, '';
+}
+
+sub config {
+ my $self = shift;
+
+ my @report = ();
+
+ # core config
+ push @report, ModPerl::Config::as_string();
+
+ # installed packages
+ push @report, $self->packages;
+
+ # this report is generated by user/group
+
+ return join "\n", @report;
+}
+
+sub package2filename {
+ my $package = shift;
+ $package =~ s|::|/|g;
+ $package .= ".pm";
+ return $package;
+}
+
+sub report_to { 'modperl@perl.apache.org' }
+
+
+1;
diff --git a/2_0_13/lib/ModPerl/TestRun.pm b/2_0_13/lib/ModPerl/TestRun.pm
new file mode 100644
index 0000000..eb37692
--- /dev/null
+++ b/2_0_13/lib/ModPerl/TestRun.pm
@@ -0,0 +1,74 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::TestRun;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache::TestRunPerl);
+
+use Apache2::Build;
+
+# some mp2 tests require more than one server instance to be available
+# without which the server may hang, waiting for the single server
+# become available
+use constant MIN_CLIENTS => 2;
+
+sub new_test_config {
+ my $self = shift;
+
+ # default timeout in secs (threaded mpms are extremely slow to
+ # startup, due to a slow perl_clone operation)
+ $self->{conf_opts}->{startup_timeout} ||=
+ $ENV{APACHE_TEST_STARTUP_TIMEOUT} ||
+ Apache2::Build->build_config->mpm_is_threaded() ? 300 : 120;
+
+ $self->{conf_opts}->{minclients} ||= MIN_CLIENTS;
+
+ ModPerl::TestConfig->new($self->{conf_opts});
+}
+
+sub bug_report {
+ my $self = shift;
+
+ print <<EOI;
++--------------------------------------------------------+
+| Please file a bug report: http://perl.apache.org/bugs/ |
++--------------------------------------------------------+
+EOI
+}
+
+package ModPerl::TestConfig;
+
+use base qw(Apache::TestConfig);
+
+sub new {
+ my $class = shift;
+ my $self = $class->SUPER::new(@_);
+ my $config = Apache2::Build->build_config;
+ $self->{conf_opts}->{httpd} ||= $config->{httpd};
+ return $self;
+}
+
+# - don't inherit LoadModule perl_module from the apache httpd.conf
+# - loaded fastcgi crashes some mp2 tests
+my @skip = ('mod_perl.c', qr/mod_fastcgi.*?\.c$/);
+
+Apache::TestConfig::autoconfig_skip_module_add(@skip);
+
+1;
+
diff --git a/2_0_13/lib/ModPerl/TypeMap.pm b/2_0_13/lib/ModPerl/TypeMap.pm
new file mode 100644
index 0000000..5548cca
--- /dev/null
+++ b/2_0_13/lib/ModPerl/TypeMap.pm
@@ -0,0 +1,534 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::TypeMap;
+
+use strict;
+use warnings FATAL => 'all';
+
+use ModPerl::FunctionMap ();
+use ModPerl::StructureMap ();
+use ModPerl::MapUtil qw(list_first);
+
+our @ISA = qw(ModPerl::MapBase);
+
+sub new {
+ my $class = shift;
+
+ my $self = bless {
+ INCLUDE => [],
+ struct => [],
+ typedef => [],
+ }, $class;
+
+ $self->{function_map} = ModPerl::FunctionMap->new,
+ $self->{structure_map} = ModPerl::StructureMap->new,
+
+ $self->get;
+ $self;
+}
+
+my %special = map { $_, 1 } qw(UNDEFINED NOTIMPL CALLBACK);
+
+sub special {
+ my ($self, $class) = @_;
+ return $special{$class};
+}
+
+sub function_map { shift->{function_map}->get }
+sub structure_map { shift->{structure_map}->get }
+
+sub parse {
+ my ($self, $fh, $map) = @_;
+
+ while ($fh->readline) {
+ if (/E=/) {
+ my %args = $self->parse_keywords($_);
+ while (my ($key,$val) = each %args) {
+ push @{ $self->{$key} }, $val;
+ }
+ next;
+ }
+
+ my @aliases;
+ my ($type, $class) = (split /\s*\|\s*/, $_)[0,1];
+ $class ||= 'UNDEFINED';
+
+ if ($type =~ s/^(struct|typedef)\s+(.*)/$2/) {
+ my $typemap = $1;
+ push @aliases, $type;
+
+ if ($typemap eq 'struct') {
+ push @aliases, "const $type", "$type *", "const $type *",
+ "struct $type *", "const struct $type *",
+ "$type **";
+ }
+
+ my $cname = $class;
+ if ($cname =~ s/::/__/g) {
+ push @{ $self->{$typemap} }, [$type, $cname];
+ }
+ }
+ elsif ($type =~ /_t$/) {
+ push @aliases, $type, "$type *", "const $type *";
+ }
+ else {
+ push @aliases, $type;
+ }
+
+ for (@aliases) {
+ $map->{$_} = $class;
+ }
+ }
+}
+
+sub get {
+ my $self = shift;
+
+ $self->{map} ||= $self->parse_map_files;
+}
+
+my $ignore = join '|', qw{
+ap_LINK ap_HOOK _ UINT union._
+union.block_hdr cleanup process_chain
+iovec struct.rlimit Sigfunc in_addr_t
+};
+
+sub should_ignore {
+ my ($self, $type) = @_;
+ return 1 if $type =~ /^($ignore)/o;
+}
+
+sub is_callback {
+ my ($self, $type) = @_;
+ return 1 if $type =~ /\(/ and $type =~ /\)/; #XXX: callback
+}
+
+sub exists {
+ my ($self, $type) = @_;
+
+ return 1 if $self->is_callback($type) || $self->should_ignore($type);
+
+ $type =~ s/\[\d+\]$//; #char foo[64]
+
+ return exists $self->get->{$type};
+}
+
+sub map_type {
+ my ($self, $type) = @_;
+ my $class = $self->get->{$type};
+
+ return unless $class and ! $self->special($class);
+# return if $type =~ /\*\*$/; #XXX
+ if ($class =~ /::/) {
+ return $class;
+ }
+ else {
+ return $type;
+ }
+}
+
+sub null_type {
+ my ($self, $type) = @_;
+ my $class = $self->get->{$type};
+
+ if ($class =~ /^[INU]V/) {
+ return '0';
+ }
+ else {
+ return 'NULL';
+ }
+}
+
+sub can_map {
+ my $self = shift;
+ my $map = shift;
+
+ return 1 if $map->{argspec};
+
+ for (@_) {
+ return (0, $_) unless $self->map_type($_);
+ }
+
+ return 1;
+}
+
+sub map_arg {
+ my ($self, $arg) = @_;
+
+ my $map_type = $self->map_type($arg->{type});
+ die "unknown typemap: '$arg->{type}'" unless defined $map_type;
+
+ return {
+ name => $arg->{name},
+ default => $arg->{default},
+ type => $map_type,
+ rtype => $arg->{type},
+ }
+}
+
+sub map_args {
+ my ($self, $func) = @_;
+
+ my $entry = $self->function_map->{ $func->{name} };
+ my $argspec = $entry->{argspec};
+ my $args = [];
+
+ if ($argspec) {
+ $entry->{orig_args} = [ map $_->{name}, @{ $func->{args} } ];
+
+ for my $arg (@$argspec) {
+ my $default;
+ ($arg, $default) = split /=/, $arg, 2;
+ my ($type, $name) = split ':', $arg, 2;
+
+ if ($type and $name) {
+ push @$args, {
+ name => $name,
+ type => $type,
+ default => $default,
+ };
+ }
+ else {
+ my $e = list_first { $_->{name} eq $arg } @{ $func->{args} };
+ if ($e) {
+ push @$args, { %$e, default => $default };
+ }
+ elsif ($arg eq '...') {
+ push @$args, { name => '...', type => 'SV *' };
+ }
+ else {
+ warn "bad argspec: $func->{name} ($arg)\n";
+ }
+ }
+ }
+ }
+ else {
+ $args = $func->{args};
+ }
+
+ return [ map $self->map_arg($_), @$args ]
+}
+
+#this is needed for modperl-only functions
+#unlike apache/apr functions which are remapped to a mpxs_ function
+sub thx_fixup {
+ my ($self, $func) = @_;
+
+ my $first = $func->{args}->[0];
+
+ return unless $first;
+
+ if ($first->{type} =~ /PerlInterpreter/) {
+ shift @{ $func->{args} };
+ $func->{thx} = 1;
+ }
+}
+
+sub map_function {
+ my ($self, $func) = @_;
+
+ my $map = $self->function_map->{ $func->{name} };
+ return unless $map;
+
+ $self->thx_fixup($func);
+
+ my ($status, $failed_type) =
+ $self->can_map($map, $func->{return_type},
+ map $_->{type}, @{ $func->{args} });
+
+ unless ($status) {
+ warn "unknown typemap: '$failed_type' (skipping $func->{name})\n";
+ return;
+ }
+
+ my $type = $map->{return_type} || $func->{return_type} || 'void';
+ my $map_type = $self->map_type($type);
+ die "unknown typemap: '$type'" unless defined $map_type;
+
+ my $mf = {
+ name => $func->{name},
+ return_type => $map_type,
+ args => $self->map_args($func),
+ perl_name => $map->{name},
+ thx => $func->{thx},
+ };
+
+ for (qw(dispatch argspec orig_args prefix)) {
+ $mf->{$_} = $map->{$_};
+ }
+
+ unless ($mf->{class}) {
+ $mf->{class} = $map->{class} || $self->first_class($mf);
+ #print "GUESS class=$mf->{class} for $mf->{name}\n";
+ }
+
+ $mf->{prefix} ||= ModPerl::FunctionMap::guess_prefix($mf);
+
+ $mf->{module} = $map->{module} || $mf->{class};
+
+ $mf;
+}
+
+sub map_structure {
+ my ($self, $struct) = @_;
+
+ my ($class, @elts);
+ my $stype = $struct->{type};
+
+ return unless $class = $self->map_type($stype);
+
+ for my $e (@{ $struct->{elts} }) {
+ my ($name, $type) = ($e->{name}, $e->{type});
+ my $rtype;
+
+ # ro/rw/r+w_startup/undef(disabled)
+ my $access_mode = $self->structure_map->{$stype}->{$name};
+ next unless $access_mode;
+ next unless $rtype = $self->map_type($type);
+
+ push @elts, {
+ name => $name,
+ type => $rtype,
+ default => $self->null_type($type),
+ pool => $self->class_pool($class),
+ class => $self->{map}->{$type} || "",
+ access_mode => $access_mode,
+ };
+ }
+
+ return {
+ module => $self->{structure_map}->{MODULES}->{$stype} || $class,
+ class => $class,
+ type => $stype,
+ elts => \@elts,
+ };
+}
+
+sub destructor {
+ my ($self, $prefix) = @_;
+ $self->function_map->{$prefix . 'DESTROY'};
+}
+
+sub first_class {
+ my ($self, $func) = @_;
+
+ for my $e (@{ $func->{args} }) {
+ next unless $e->{type} =~ /::/;
+ #there are alot of util functions that take an APR::Pool
+ #that do not belong in the APR::Pool class
+ next if $e->{type} eq 'APR::Pool' and $func->{name} !~ /^apr_pool/;
+ return $e->{type};
+ }
+
+ return $func->{name} =~ /^apr_/ ? 'APR' : 'Apache2';
+}
+
+sub check {
+ my $self = shift;
+
+ my (@types, @missing, %seen);
+
+ require Apache2::StructureTable;
+ for my $entry (@$Apache2::StructureTable) {
+ push @types, map $_->{type}, @{ $entry->{elts} };
+ }
+
+ for my $entry (@$Apache2::FunctionTable) {
+ push @types, grep { not $seen{$_}++ }
+ ($entry->{return_type},
+ map $_->{type}, @{ $entry->{args} })
+ }
+
+ #printf "%d types\n", scalar @types;
+
+ for my $type (@types) {
+ push @missing, $type unless $self->exists($type);
+ }
+
+ return @missing ? \@missing : undef;
+}
+
+#look for Apache/APR structures that do not exist in structure.map
+my %ignore_check = map { $_,1 } qw{
+module_struct cmd_how kill_conditions
+regex_t regmatch_t pthread_mutex_t
+unsigned void va_list ... iovec char int long const
+gid_t uid_t time_t pid_t size_t
+sockaddr hostent
+SV
+};
+
+sub check_exists {
+ my $self = shift;
+
+ my %structures = map { $_->{type}, 1 } @{ $self->structure_table() };
+ my @missing = ();
+ my %seen;
+
+ for my $name (keys %{ $self->{map} }) {
+ 1 while $name =~ s/^\w+\s+(\w+)/$1/;
+ $name =~ s/\s+\**.*$//;
+ next if $seen{$name}++ or $structures{$name} or $ignore_check{$name};
+ push @missing, $name;
+ }
+
+ return @missing ? \@missing : undef;
+}
+
+#XXX: generate this
+my %class_pools = map {
+ (my $f = "mpxs_${_}_pool") =~ s/:/_/g;
+ $_, $f;
+} qw{
+ Apache2::RequestRec Apache2::Connection Apache2::URI APR::URI
+};
+
+sub class_pool : lvalue {
+ my ($self, $class) = @_;
+ $class_pools{$class};
+}
+
+#anything needed that mod_perl.h does not already include
+#XXX: .maps should INCLUDE= these
+my @includes = qw{
+apr_uuid.h
+apr_sha1.h
+apr_md5.h
+apr_base64.h
+apr_getopt.h
+apr_hash.h
+apr_lib.h
+apr_general.h
+apr_signal.h
+apr_thread_rwlock.h
+util_script.h
+};
+
+sub h_wrap {
+ my ($self, $file, $code) = @_;
+
+ $file = 'modperl_xs_' . $file;
+
+ my $h_def = uc "${file}_h";
+ my $preamble = "\#ifndef $h_def\n\#define $h_def\n\n";
+ my $postamble = "\n\#endif /* $h_def */\n";
+
+ return ("$file.h", $preamble . $code . $postamble);
+}
+
+sub typedefs_code {
+ my $self = shift;
+ my $map = $self->get;
+ my %seen;
+
+ my $file = 'modperl_xs_typedefs';
+ my $h_def = uc "${file}_h";
+ my $code = "";
+
+ for (@includes, @{ $self->{INCLUDE} }) {
+ $code .= qq{\#include "$_"\n}
+ }
+
+ for my $t (sort {$a->[1] cmp $b->[1]} @{ $self->{struct} }) {
+ next if $seen{ $t->[1] }++;
+ $code .= "typedef $t->[0] * $t->[1];\n";
+ }
+
+ for my $t (sort {$a->[1] cmp $b->[1]} @{ $self->{typedef} }) {
+ next if $seen{ $t->[1] }++;
+ $code .= "typedef $t->[0] $t->[1];\n";
+ }
+
+ $self->h_wrap('typedefs', $code);
+}
+
+my %convert_alias = (
+ Apache2__RequestRec => 'r',
+ Apache2__Server => 'server',
+ Apache2__Connection => 'connection',
+ APR__Table => 'table',
+ APR__UUID => 'uuid',
+ apr_status_t => 'status',
+);
+
+sub sv_convert_code {
+ my $self = shift;
+ my $map = $self->get;
+ my %seen;
+ my $code = "";
+
+ for my $ctype (sort keys %$map) {
+ my $ptype = $map->{$ctype};
+
+ next if $self->special($ptype);
+ next if $ctype =~ /\s/;
+ my $class = $ptype;
+
+ if ($ptype =~ s/:/_/g) {
+ next if $seen{$ptype}++;
+
+ my $alias;
+ my $expect = "expecting an $class derived object";
+ my $croak = "argument is not a blessed reference";
+
+ #Perl -> C
+ my $define = "mp_xs_sv2_$ptype";
+
+ $code .= <<EOF;
+#define $define(sv) \\
+((SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) \\
+|| (Perl_croak(aTHX_ "$croak ($expect)"),0) ? \\
+INT2PTR($ctype *, SvIV((SV*)SvRV(sv))) : ($ctype *)NULL)
+
+EOF
+
+ if ($alias = $convert_alias{$ptype}) {
+ $code .= "#define mp_xs_sv2_$alias $define\n\n";
+ }
+
+ #C -> Perl
+ $define = "mp_xs_${ptype}_2obj";
+
+ $code .= <<EOF;
+#define $define(ptr) \\
+sv_setref_pv(sv_newmortal(), "$class", (void*)ptr)
+
+EOF
+
+ if ($alias) {
+ $code .= "#define mp_xs_${alias}_2obj $define\n\n";
+ }
+ }
+ else {
+ if ($ptype =~ /^(\wV)$/) {
+ my $class = $1;
+ my $define = "mp_xs_sv2_$ctype";
+
+ $code .= "#define $define(sv) ($ctype)Sv$class(sv)\n\n";
+
+ if (my $alias = $convert_alias{$ctype}) {
+ $code .= "#define mp_xs_sv2_$alias $define\n\n";
+ }
+ }
+ }
+ }
+
+ $self->h_wrap('sv_convert', $code);
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/ModPerl/WrapXS.pm b/2_0_13/lib/ModPerl/WrapXS.pm
new file mode 100644
index 0000000..9f5cb08
--- /dev/null
+++ b/2_0_13/lib/ModPerl/WrapXS.pm
@@ -0,0 +1,1401 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::WrapXS;
+
+use strict;
+use warnings FATAL => 'all';
+
+use constant GvUNIQUE => 0; #$] >= 5.008;
+use Apache::TestTrace;
+use Apache2::Build ();
+use ModPerl::Code ();
+use ModPerl::TypeMap ();
+use ModPerl::MapUtil qw(function_table xs_glue_dirs);
+use File::Path qw(rmtree mkpath);
+use Cwd qw(fastcwd);
+use Data::Dumper;
+use File::Spec::Functions qw(catfile catdir);
+
+our $VERSION = '0.01';
+
+my (@xs_includes) = ('mod_perl.h',
+ map "modperl_xs_$_.h", qw(sv_convert util typedefs));
+
+my @global_structs = qw(perl_module);
+
+my $build = Apache2::Build->build_config;
+push @global_structs, 'MP_debug_level' unless Apache2::Build::WIN32;
+
+sub new {
+ my $class = shift;
+
+ my $self = bless {
+ typemap => ModPerl::TypeMap->new,
+ includes => \@xs_includes,
+ glue_dirs => [xs_glue_dirs()],
+ }, $class;
+
+ $self->typemap->get;
+ $self;
+}
+
+sub typemap { shift->{typemap} }
+
+sub includes { shift->{includes} }
+
+sub function_list {
+ my $self = shift;
+ my (@list) = @{ function_table() };
+
+ while (my ($name, $val) = each %{ $self->typemap->function_map }) {
+ #entries that do not exist in C::Scan generated tables
+ next unless $name =~ /^DEFINE_/;
+ push @list, $val;
+ }
+
+ return \@list;
+}
+
+sub get_functions {
+ my $self = shift;
+ my $typemap = $self->typemap;
+
+ for my $entry (sort { $a->{name} cmp $b->{name} } @{ $self->function_list() }) {
+ my $func = $typemap->map_function($entry);
+ #print "FAILED to map $entry->{name}\n" unless $func;
+ next unless $func;
+
+ my ($name, $module, $class, $args) =
+ @{ $func } { qw(perl_name module class args) };
+
+ $self->{XS}->{ $module } ||= [];
+
+ #eg ap_fputs()
+ if ($name =~ s/^DEFINE_//) {
+ $func->{name} =~ s/^DEFINE_//;
+
+ if (needs_prefix($func->{name})) {
+ #e.g. DEFINE_add_output_filter
+ $func->{name} = make_prefix($func->{name}, $class);
+ }
+ }
+
+ my $xs_parms = join ', ',
+ map { defined $_->{default} ?
+ "$_->{name}=$_->{default}" : $_->{name} } @$args;
+
+ (my $parms = $xs_parms) =~ s/=[^,]+//g; #strip defaults
+
+ my $proto = join "\n",
+ (map " $_->{type} $_->{name}", @$args), "";
+
+ my ($dispatch, $orig_args) =
+ @{ $func } {qw(dispatch orig_args)};
+
+ if ($dispatch =~ /^MPXS_/) {
+ $name =~ s/^mpxs_//;
+ $name =~ s/^$func->{prefix}//;
+ push @{ $self->{newXS}->{ $module } },
+ ["$class\::$name", $dispatch];
+ next;
+ }
+
+ my $passthru = @$args && $args->[0]->{name} eq '...';
+ if ($passthru) {
+ $parms = '...';
+ $proto = '';
+ }
+
+ my $return_type =
+ $name =~ /^DESTROY$/ ? 'void' : $func->{return_type};
+
+ my $attrs = $self->attrs($name);
+
+ my $code = <<EOF;
+$return_type
+$name($xs_parms)
+$proto
+$attrs
+EOF
+
+ if ($dispatch || $orig_args || $func->{thx}) {
+ my $thx = $func->{thx} ? 'aTHX_ ' : "";
+
+ if ($dispatch) {
+ $thx = 'aTHX_ ' if $dispatch =~ /^mpxs_/i;
+ }
+ else {
+ if ($orig_args and @$orig_args == @$args) {
+ #args were reordered
+ $parms = join ', ', @$orig_args;
+ }
+
+ $dispatch = $func->{name};
+ }
+
+ if ($passthru) {
+ $thx ||= 'aTHX_ ';
+ $parms = 'items, MARK+1, SP';
+ }
+
+ $thx =~ s/_ $// unless $parms;
+
+ my $retval = $return_type eq 'void' ?
+ ["", ""] : ["RETVAL = ", "OUTPUT:\n RETVAL\n"];
+
+ my $avoid_warning = "";
+ if (@$args and not $passthru) {
+ $avoid_warning = " /* avoiding -Wall warnings */\n";
+ $avoid_warning .= join "\n",
+ (map " $_->{name} = $_->{name};", @$args), "";
+ }
+ $code .= <<EOF;
+ CODE:
+$avoid_warning
+ $retval->[0]$dispatch($thx$parms);
+
+ $retval->[1]
+EOF
+ }
+
+ $func->{code} = $code;
+ push @{ $self->{XS}->{ $module } }, $func;
+ }
+}
+
+sub get_value {
+ my $e = shift;
+ my $val = 'val';
+
+ if ($e->{class} eq 'PV') {
+ if (my $pool = $e->{pool}) {
+ $pool .= '(obj)';
+ $val = "(SvOK(ST(1)) ?
+ apr_pstrndup($pool, val, val_len) : NULL)"
+ }
+ }
+
+ return $val;
+}
+
+sub get_structures {
+ my $self = shift;
+ my $typemap = $self->typemap;
+
+ require Apache2::StructureTable;
+ for my $entry (@$Apache2::StructureTable) {
+ my $struct = $typemap->map_structure($entry);
+ next unless $struct;
+
+ my $class = $struct->{class};
+
+ for my $e (@{ $struct->{elts} }) {
+ my ($name, $default, $type, $access_mode) =
+ @{$e}{qw(name default type access_mode)};
+
+ (my $cast = $type) =~ s/:/_/g;
+ my $val = get_value($e);
+
+ my $type_in = $type;
+ my $preinit = "/*nada*/";
+ if ($e->{class} eq 'PV' and $val ne 'val') {
+ $type_in =~ s/char/char_len/;
+ $preinit = "STRLEN val_len;";
+ }
+
+ my $attrs = $self->attrs($name);
+
+ my $code;
+ if ($access_mode eq 'ro') {
+ $code = <<EOF;
+$type
+$name(obj)
+ $class obj
+
+$attrs
+
+ CODE:
+ RETVAL = ($cast) obj->$name;
+
+ OUTPUT:
+ RETVAL
+
+EOF
+ }
+ elsif ($access_mode eq 'rw' or $access_mode eq 'r+w_startup') {
+
+ my $check_runtime = $access_mode eq 'rw'
+ ? ''
+ : qq[MP_CROAK_IF_THREADS_STARTED("setting $name");];
+
+ $code = <<EOF;
+$type
+$name(obj, val=$default)
+ $class obj
+ $type_in val
+
+ PREINIT:
+ $preinit
+$attrs
+
+ CODE:
+ RETVAL = ($cast) obj->$name;
+
+ if (items > 1) {
+ $check_runtime
+ obj->$name = ($cast) $val;
+ }
+
+ OUTPUT:
+ RETVAL
+
+EOF
+ }
+ elsif ($access_mode eq 'r+w_startup_dup') {
+
+ my $convert = $cast !~ /\bchar\b/
+ ? "mp_xs_sv2_$cast"
+ : "SvPV_nolen";
+
+ $code = <<EOF;
+$type
+$name(obj, val=(SV *)NULL)
+ $class obj
+ SV *val
+
+ PREINIT:
+ $preinit
+$attrs
+
+ CODE:
+ RETVAL = ($cast) obj->$name;
+
+ if (items > 1) {
+ SV *dup = get_sv("_modperl_private::server_rec_$name", TRUE);
+ MP_CROAK_IF_THREADS_STARTED("setting $name");
+ sv_setsv(dup, val);
+ obj->$name = ($cast)$convert(dup);
+ }
+
+ OUTPUT:
+ RETVAL
+
+EOF
+ }
+ elsif ($access_mode eq 'rw_char_undef') {
+ my $pool = $e->{pool}
+ or die "rw_char_undef accessors need pool";
+ $pool .= '(obj)';
+# XXX: not sure where val=$default is coming from, but for now use
+# hardcoded (SV *)NULL
+ $code = <<EOF;
+$type
+$name(obj, val_sv=(SV *)NULL)
+ $class obj
+ SV *val_sv
+
+ PREINIT:
+$attrs
+
+ CODE:
+ RETVAL = ($cast) obj->$name;
+
+ if (val_sv) {
+ if (SvOK(val_sv)) {
+ STRLEN val_len;
+ char *val = (char *)SvPV(val_sv, val_len);
+ obj->$name = apr_pstrndup($pool, val, val_len);
+ }
+ else {
+ obj->$name = NULL;
+ }
+ }
+
+ OUTPUT:
+ RETVAL
+
+EOF
+ }
+
+ push @{ $self->{XS}->{ $struct->{module} } }, {
+ code => $code,
+ class => $class,
+ name => $name,
+ };
+ }
+ }
+}
+
+sub prepare {
+ my $self = shift;
+ $self->{DIR} = 'WrapXS';
+ $self->{XS_DIR} = catdir fastcwd(), 'xs';
+
+ my $verbose = Apache::TestTrace::trace_level() eq 'debug' ? 1 : 0;
+
+ if (-e $self->{DIR}) {
+ rmtree([$self->{DIR}], $verbose, 1);
+ }
+
+ mkpath [$self->{DIR}], $verbose, 0755;
+}
+
+sub class_dirname {
+ my ($self, $class) = @_;
+ my ($base, $sub) = split '::', $class;
+ return "$self->{DIR}/$base" unless $sub; #Apache2 | APR
+ return $sub if $sub eq $self->{DIR}; #WrapXS
+ return "$base/$sub";
+}
+
+sub class_dir {
+ my ($self, $class) = @_;
+
+ my $dirname = $self->class_dirname($class);
+ my $dir = ($dirname =~ m:/: and $dirname !~ m:^$self->{DIR}:) ?
+ catdir($self->{DIR}, $dirname) : $dirname;
+
+ unless (-d $dir) {
+ mkpath [$dir], 0, 0755;
+ debug "mkdir.....$dir";
+ }
+
+ $dir;
+}
+
+sub class_file {
+ my ($self, $class, $file) = @_;
+ catfile $self->class_dir($class), $file;
+}
+
+sub cname {
+ my ($self, $class) = @_;
+ $class =~ s/:/_/g;
+ $class;
+}
+
+sub open_class_file {
+ my ($self, $class, $file) = @_;
+
+ if ($file =~ /^\./) {
+ my $sub = (split '::', $class)[-1];
+ $file = $sub . $file;
+ }
+
+ my $name = $self->class_file($class, $file);
+
+ open my $fh, '>', $name or die "open $name: $!";
+ debug "writing...$name";
+
+ return $fh;
+}
+
+sub module_version {
+ local $_ = shift;
+ require mod_perl2;
+ # XXX: for now APR gets its libapr-0.9 version
+ return /^APR/ ? "0.009000" : "$mod_perl2::VERSION";
+}
+
+sub write_makefilepl {
+ my ($self, $class) = @_;
+
+ my $fh = $self->open_class_file($class, 'Makefile.PL');
+
+ my $includes = $self->includes;
+ my $xs = (split '::', $class)[-1] . '.c';
+ my $deps = {$xs => ""};
+
+ if (my $mod_h = $self->mod_h($class, 1)) {
+ $deps->{$xs} .= " $mod_h";
+ }
+
+ local $Data::Dumper::Terse = 1;
+ $deps = Dumper $deps;
+
+ my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash();
+ require mod_perl2;
+ my $version = module_version($class);
+
+ print $fh <<EOF;
+$noedit_warning
+
+use lib qw(../../../lib); #for Apache2::BuildConfig
+use ModPerl::BuildMM ();
+
+ModPerl::BuildMM::WriteMakefile(
+ 'NAME' => '$class',
+ 'VERSION' => '$version',
+ 'depend' => $deps,
+);
+EOF
+
+ close $fh;
+}
+
+sub mod_h {
+ my ($self, $module, $complete) = @_;
+
+ my $dirname = $self->class_dirname($module);
+ my $cname = $self->cname($module);
+ my $mod_h = "$dirname/$cname.h";
+
+ for ($self->{XS_DIR}, @{ $self->{glue_dirs} }) {
+ my $file = "$_/$mod_h";
+ $mod_h = $file if $complete;
+ return $mod_h if -e $file;
+ }
+
+ undef;
+}
+
+sub mod_pm {
+ my ($self, $module, $complete) = @_;
+
+ my $dirname = $self->class_dirname($module);
+ my ($base, $sub) = split '::', $module;
+ my $mod_pm = "$dirname/${sub}_pm";
+
+ for ($self->{XS_DIR}, @{ $self->{glue_dirs} }) {
+ my $file = "$_/$mod_pm";
+ $mod_pm = $file if $complete;
+ return $mod_pm if -e $file;
+ }
+
+ undef;
+}
+
+sub class_c_prefix {
+ my $class = shift;
+ $class =~ s/:/_/g;
+ $class;
+}
+
+sub class_mpxs_prefix {
+ my $class = shift;
+ my $class_prefix = class_c_prefix($class);
+ "mpxs_${class_prefix}_";
+}
+
+sub needs_prefix {
+ my $name = shift;
+ $name !~ /^(ap|apr|mpxs)_/i;
+}
+
+sub make_prefix {
+ my ($name, $class) = @_;
+ my $class_prefix = class_mpxs_prefix($class);
+ return $name if $name =~ /^$class_prefix/;
+ $class_prefix . $name;
+}
+
+sub isa_str {
+ my ($self, $module) = @_;
+ my $str = "";
+
+ if (my $isa = $self->typemap->{function_map}->{isa}->{$module}) {
+ foreach my $sub (sort keys %$isa) {
+ my $base = $isa->{$sub};
+#XXX cannot set isa in the BOOT: section because XSLoader local-ises
+#ISA during bootstrap
+# $str .= qq{ av_push(get_av("$sub\::ISA", TRUE),
+# newSVpv("$base",0));}
+ $str .= qq{\@$sub\::ISA = '$base';\n}
+ }
+ }
+
+ $str;
+}
+
+sub boot {
+ my ($self, $module) = @_;
+ my $str = "";
+
+ if (my $boot = $self->typemap->{function_map}->{boot}->{$module}) {
+ $str = ' mpxs_' . $self->cname($module) . "_BOOT(aTHX);\n";
+ }
+
+ $str;
+}
+
+my $notshared = join '|', qw(TIEHANDLE); #not sure why yet
+
+sub attrs {
+ my ($self, $name) = @_;
+ my $str = "";
+ return $str if $name =~ /$notshared$/o;
+ $str = " ATTRS: unique\n" if GvUNIQUE;
+ $str;
+}
+
+sub write_xs {
+ my ($self, $module, $functions) = @_;
+
+ my $fh = $self->open_class_file($module, '.xs');
+ print $fh $self->ModPerl::Code::noedit_warning_c(), "\n";
+ print $fh "\n#define MP_IN_XS\n\n";
+
+ my @includes = @{ $self->includes };
+
+ if (my $mod_h = $self->mod_h($module)) {
+ push @includes, $mod_h;
+ }
+
+ for (@includes) {
+ print $fh qq{\#include "$_"\n\n};
+ }
+
+ my $last_prefix = "";
+
+ for my $func (@$functions) {
+ my $class = $func->{class};
+ my $prefix = $func->{prefix};
+ $last_prefix = $prefix if $prefix;
+
+ if ($func->{name} =~ /^mpxs_/) {
+ #e.g. mpxs_Apache2__RequestRec_
+ my $class_prefix = class_c_prefix($class);
+ if ($func->{name} =~ /$class_prefix/) {
+ $prefix = class_mpxs_prefix($class);
+ }
+ }
+
+ $prefix = $prefix ? " PREFIX = $prefix" : "";
+ print $fh "MODULE = $module PACKAGE = $class $prefix\n\n";
+
+ print $fh $func->{code};
+ }
+
+ if (my $destructor = $self->typemap->destructor($last_prefix)) {
+ my $arg = $destructor->{argspec}[0];
+
+ print $fh <<EOF;
+void
+$destructor->{name}($arg)
+ $destructor->{class} $arg
+
+EOF
+ }
+
+ print $fh "MODULE = $module\n";
+ print $fh "PROTOTYPES: disabled\n\n";
+ print $fh "BOOT:\n";
+ print $fh $self->boot($module);
+ print $fh " items = items; /* -Wall */\n\n";
+
+ if (my $newxs = $self->{newXS}->{$module}) {
+ for my $xs (sort { $a->[0] cmp $b->[0] } @$newxs) {
+ print $fh qq{ cv = newXS("$xs->[0]", $xs->[1], __FILE__);\n};
+ print $fh qq{ GvUNIQUE_on(CvGV(cv));\n} if GvUNIQUE;
+ }
+ }
+
+ if ($module eq 'APR::Pool' && Apache2::Build::PERL_HAS_ITHREADS) {
+ print $fh " modperl_opt_interp_unselect = APR_RETRIEVE_OPTIONAL_FN(modperl_interp_unselect);\n\n";
+ print $fh " modperl_opt_thx_interp_get = APR_RETRIEVE_OPTIONAL_FN(modperl_thx_interp_get);\n\n";
+ }
+
+ close $fh;
+}
+
+sub write_pm {
+ my ($self, $module) = @_;
+
+ my $isa = $self->isa_str($module);
+
+ my $code = "";
+ if (my $mod_pm = $self->mod_pm($module, 1)) {
+ open my $fh, '<', $mod_pm;
+ local $/;
+ $code = <$fh>;
+ close $fh;
+ }
+
+ my $base = (split '::', $module)[0];
+ unless (-e "lib/$base/XSLoader.pm") {
+ $base = 'Apache2';
+ }
+ my $loader = join '::', $base, 'XSLoader';
+
+ my $fh = $self->open_class_file($module, '.pm');
+ my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash();
+ my $use_apr = ($module =~ /^APR::\w+$/) ? 'use APR ();' : '';
+ my $version = module_version($module);
+
+ print $fh <<EOF;
+$noedit_warning
+
+package $module;
+
+use strict;
+use warnings FATAL => 'all';
+
+$isa
+$use_apr
+use $loader ();
+our \$VERSION = '$version';
+$loader\::load __PACKAGE__;
+
+$code
+
+1;
+__END__
+EOF
+}
+
+my %typemap = (
+ 'Apache2::RequestRec' => 'T_APACHEOBJ',
+ 'apr_time_t' => 'T_APR_TIME',
+ 'APR::Table' => 'T_HASHOBJ',
+ 'APR::Pool' => 'T_POOLOBJ',
+ 'apr_size_t *' => 'T_UVPTR',
+);
+
+sub write_typemap {
+ my $self = shift;
+ my $typemap = $self->typemap;
+ my $map = $typemap->get;
+ my %seen;
+
+ my $fh = $self->open_class_file('ModPerl::WrapXS', 'typemap');
+ print $fh $self->ModPerl::Code::noedit_warning_hash(), "\n";
+
+ my %entries = ();
+ my $max_key_len = 0;
+ while (my ($type, $class) = each %$map) {
+ $class ||= $type;
+ next if $seen{$type}++ || $typemap->special($class);
+
+ if ($class =~ /::/) {
+ $entries{$class} = $typemap{$class} || 'T_PTROBJ';
+ $max_key_len = length $class if length $class > $max_key_len;
+ }
+ else {
+ $entries{$type} = $typemap{$type} || "T_$class";
+ $max_key_len = length $type if length $type > $max_key_len;
+ }
+ }
+
+ for (sort keys %entries) {
+ printf $fh "%-${max_key_len}s %s\n", $_, $entries{$_};
+ }
+
+ close $fh;
+}
+
+sub write_typemap_h_file {
+ my ($self, $method) = @_;
+
+ $method = $method . '_code';
+ my ($h, $code) = $self->typemap->$method();
+ my $file = catfile $self->{XS_DIR}, $h;
+
+ open my $fh, '>', $file or die "open $file: $!";
+ print $fh $self->ModPerl::Code::noedit_warning_c(), "\n";
+ print $fh $code;
+ close $fh;
+}
+
+sub write_lookup_method_file {
+ my $self = shift;
+
+ my %map = ();
+ foreach my $module (sort keys %{ $self->{XS} }) {
+ my $functions = $self->{XS}->{$module};
+ my $last_prefix = "";
+ for my $func (@$functions) {
+ my $class = $func->{class};
+ my $prefix = $func->{prefix};
+ $last_prefix = $prefix if $prefix;
+
+ my $name = $func->{perl_name} || $func->{name};
+ $name =~ s/^DEFINE_//;
+
+ if ($name =~ /^mpxs_/) {
+ #e.g. mpxs_Apache2__RequestRec_
+ my $class_prefix = class_c_prefix($class);
+ if ($name =~ /$class_prefix/) {
+ $prefix = class_mpxs_prefix($class);
+ }
+ }
+ elsif ($name =~ /^ap_sub_req/) {
+ $prefix = 'ap_sub_req_';
+ }
+
+ $name =~ s/^$prefix// if $prefix;
+
+ push @{ $map{$name} }, [$module, $class];
+ }
+
+ # pure XS wrappers don't have the information about the
+ # arguments they receive, since they manipulate the arguments
+ # stack directly. therefore for these methods we can't tell
+ # what are the objects they are invoked on
+ for my $xs (@{ $self->{newXS}->{$module} || []}) {
+ push @{ $map{$1} }, [$module, undef] if $xs->[0] =~ /.+::(.+)/;
+ }
+ }
+
+ local $Data::Dumper::Terse = 1;
+ local $Data::Dumper::Sortkeys = 1;
+ $Data::Dumper::Terse = $Data::Dumper::Terse; # warn
+ $Data::Dumper::Sortkeys = $Data::Dumper::Sortkeys; # warn
+ my $methods = Dumper(\%map);
+ $methods =~ s/\n$//;
+
+ my $package = "ModPerl::MethodLookup";
+ my $file = catfile "lib", "ModPerl", "MethodLookup.pm";
+ debug "creating $file";
+ open my $fh, ">$file" or die "Can't open $file: $!";
+
+ my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash();
+
+ print $fh <<EOF;
+$noedit_warning
+package $package;
+
+use strict;
+use warnings;
+
+my \$methods = $methods;
+
+EOF
+
+ print $fh <<'EOF';
+
+use base qw(Exporter);
+use mod_perl2;
+
+our @EXPORT = qw(print_method print_module print_object);
+our $VERSION = $mod_perl2::VERSION;
+use constant MODULE => 0;
+use constant OBJECT => 1;
+
+my $modules;
+my $objects;
+
+sub _get_modules {
+ for my $method (sort keys %$methods) {
+ for my $item ( @{ $methods->{$method} }) {
+ push @{ $modules->{$item->[MODULE]} }, [$method, $item->[OBJECT]];
+ }
+ }
+}
+
+sub _get_objects {
+ for my $method (sort keys %$methods) {
+ for my $item ( @{ $methods->{$method} }) {
+ next unless defined $item->[OBJECT];
+ push @{ $objects->{$item->[OBJECT]} }, [$method, $item->[MODULE]];
+ }
+ }
+}
+
+# if there is only one replacement method in 2.0 API we can
+# automatically lookup it, up however if there are more than one
+# (e.g. new()), we need to use a fully qualified value here
+# of course the same if the package is not a mod_perl one.
+#
+# the first field represents the replacement method or undef if none
+# exists, the second field is for extra comments (e.g. when there is
+# no replacement method)
+my $methods_compat = {
+ # Apache2::
+ gensym => ['Symbol::gensym',
+ 'or use "open my $fh, $file"'],
+ module => ['Apache2::Module::loaded',
+ ''],
+ define => ['exists_config_define',
+ ''],
+ httpd_conf => ['add_config',
+ ''],
+ SERVER_VERSION => ['get_server_version',
+ ''],
+ can_stack_handlers=> [undef,
+ 'there is no more need for that method in mp2'],
+
+ # Apache2::RequestRec
+ soft_timeout => [undef,
+ 'there is no more need for that method in mp2'],
+ hard_timeout => [undef,
+ 'there is no more need for that method in mp2'],
+ kill_timeout => [undef,
+ 'there is no more need for that method in mp2'],
+ reset_timeout => [undef,
+ 'there is no more need for that method in mp2'],
+ cleanup_for_exec => [undef,
+ 'there is no more need for that method in mp2'],
+ send_http_header => ['content_type',
+ ''],
+ header_in => ['headers_in',
+ 'this method works in mod_perl 1.0 too'],
+ header_out => ['headers_out',
+ 'this method works in mod_perl 1.0 too'],
+ err_header_out => ['err_headers_out',
+ 'this method works in mod_perl 1.0 too'],
+ register_cleanup => ['cleanup_register',
+ ''],
+ post_connection => ['cleanup_register',
+ ''],
+ content => [undef, # XXX: Apache2::Request::what?
+ 'use CGI.pm or Apache2::Request instead'],
+ clear_rgy_endav => ['special_list_clear',
+ ''],
+ stash_rgy_endav => [undef,
+ ''],
+ run_rgy_endav => ['special_list_call',
+ 'this method is no longer needed'],
+ seqno => [undef,
+ 'internal to mod_perl 1.0'],
+ chdir_file => [undef, # XXX: to be resolved
+ 'temporary unavailable till the issue with chdir' .
+ ' in the threaded env is resolved'],
+ log_reason => ['log_error',
+ 'not in the Apache 2.0 API'],
+ READLINE => [undef, # XXX: to be resolved
+ ''],
+ send_fd_length => [undef,
+ 'not in the Apache 2.0 API'],
+ send_fd => ['sendfile',
+ 'requires an offset argument'],
+ is_main => ['main',
+ 'not in the Apache 2.0 API'],
+ cgi_var => ['subprocess_env',
+ 'subprocess_env can be used with mod_perl 1.0'],
+ cgi_env => ['subprocess_env',
+ 'subprocess_env can be used with mod_perl 1.0'],
+ each_byterange => [undef,
+ 'now handled internally by ap_byterange_filter'],
+ set_byterange => [undef,
+ 'now handled internally by ap_byterange_filter'],
+
+ # Apache::File
+ open => [undef,
+ ''],
+ close => [undef, # XXX: also defined in APR::Socket
+ ''],
+ tmpfile => [undef,
+ 'not in the Apache 2.0 API, ' .
+ 'use File::Temp instead'],
+
+ # Apache::Util
+ size_string => ['format_size',
+ ''],
+ escape_uri => ['unescape_path',
+ ''],
+ escape_url => ['escape_path',
+ 'and requires a pool object'],
+ unescape_uri => ['unescape_url',
+ ''],
+ unescape_url_info => [undef,
+ 'use CGI::Util::unescape() instead'],
+ escape_html => [undef, # XXX: will be ap_escape_html
+ 'ap_escape_html now requires a pool object'],
+ parsedate => ['parse_http',
+ ''],
+ validate_password => ['password_validate',
+ ''],
+
+ # Apache::Table
+ #new => ['make',
+ # ''], # XXX: there are other 'new' methods
+
+ # Apache::Connection
+ auth_type => ['ap_auth_type',
+ 'now resides in the request object'],
+};
+
+sub avail_methods_compat {
+ return keys %$methods_compat;
+}
+
+sub avail_methods {
+ return keys %$methods;
+}
+
+sub avail_modules {
+ my %modules = ();
+ for my $method (keys %$methods) {
+ for my $item ( @{ $methods->{$method} }) {
+ $modules{$item->[MODULE]}++;
+ }
+ }
+ return keys %modules;
+}
+
+sub preload_all_modules {
+ _get_modules() unless $modules;
+ eval "require $_" for sort keys %$modules;
+}
+
+sub _print_func {
+ my $func = shift;
+ my @args = @_ ? @_ : @ARGV;
+ no strict 'refs';
+ print( ($func->($_))[0]) for @args;
+}
+
+sub print_module { _print_func('lookup_module', @_) }
+sub print_object { _print_func('lookup_object', @_) }
+
+sub print_method {
+ my @args = @_ ? @_ : @ARGV;
+ while (@args) {
+ my $method = shift @args;
+ my $object = (@args &&
+ (ref($args[0]) || $args[0] =~ /^(Apache2|ModPerl|APR)/))
+ ? shift @args
+ : undef;
+ print( (lookup_method($method, $object))[0]);
+ }
+}
+
+sub sep { return '-' x (shift() + 20) . "\n" }
+
+# what modules contain the passed method.
+# an optional object or a reference to it can be passed to help
+# resolve situations where there is more than one module containing
+# the same method. Inheritance is supported.
+sub lookup_method {
+ my ($method, $object) = @_;
+
+ unless (defined $method) {
+ my $hint = "No 'method' argument was passed\n";
+ return ($hint);
+ }
+
+ # strip the package name for the fully qualified method
+ $method =~ s/.+:://;
+
+ if (exists $methods_compat->{$method}) {
+ my ($replacement, $comment) = @{$methods_compat->{$method}};
+ my $hint = "'$method' is not a part of the mod_perl 2.0 API\n";
+ $comment = length $comment ? " $comment\n" : "";
+
+ # some removed methods have no replacement
+ return $hint . "$comment" unless defined $replacement;
+
+ $hint .= "use '$replacement' instead. $comment";
+
+ # if fully qualified don't look up its container
+ return $hint if $replacement =~ /::/;
+
+ my ($modules_hint, @modules) = lookup_method($replacement, $object);
+ return $hint . $modules_hint;
+ }
+ elsif (!exists $methods->{$method}) {
+ my $hint = "Don't know anything about method '$method'\n";
+ return ($hint);
+ }
+
+ my @items = @{ $methods->{$method} };
+ if (@items == 1) {
+ my $module = $items[0]->[MODULE];
+ my $hint = "To use method '$method' add:\n" . "\tuse $module ();\n";
+ # we should really check that the method matches the object if
+ # any was passed, but it may not always work
+ return ($hint, $module);
+ }
+ else {
+ if (defined $object) {
+ my $class = ref $object || $object;
+ for my $item (@items) {
+ # real class or inheritance
+ if ($class eq $item->[OBJECT] or
+ (ref($object) && $object->isa($item->[OBJECT]))) {
+ my $module = $item->[MODULE];
+ my $hint = "To use method '$method' add:\n" .
+ "\tuse $module ();\n";
+ return ($hint, $module);
+ }
+ }
+ # fall-through
+ local $" = ", ";
+ my @modules = map $_->[MODULE], @items;
+ my $hint = "Several modules (@modules) contain method '$method' " .
+ "but none of them matches class '$class';\n";
+ return ($hint);
+
+ }
+ else {
+ my %modules = map { $_->[MODULE] => 1 } @items;
+ # remove dups if any (e.g. $s->add_input_filter and
+ # $r->add_input_filter are loaded by the same Apache2::Filter)
+ my @modules = sort keys %modules;
+ my $hint;
+ if (@modules == 1) {
+ $hint = "To use method '$method' add:\n\tuse $modules[0] ();\n";
+ return ($hint, $modules[0]);
+ }
+ else {
+ $hint = "There is more than one class with method '$method'\n" .
+ "try one of:\n" . join '', map {"\tuse $_ ();\n"} @modules;
+ return ($hint, @modules);
+ }
+ }
+ }
+}
+
+# what methods are contained in the passed module name
+sub lookup_module {
+ my ($module) = shift;
+
+ unless (defined $module) {
+ my $hint = "no 'module' argument was passed\n";
+ return ($hint);
+ }
+
+ _get_modules() unless $modules;
+
+ unless (exists $modules->{$module}) {
+ my $hint = "don't know anything about module '$module'\n";
+ return ($hint);
+ }
+
+ my @methods;
+ my $max_len = 6;
+ for ( @{ $modules->{$module} } ) {
+ $max_len = length $_->[0] if length $_->[0] > $max_len;
+ push @methods, $_->[0];
+ }
+
+ my $format = "%-${max_len}s %s\n";
+ my $banner = sprintf($format, "Method", "Invoked on object type");
+ my $hint = join '',
+ ("\nModule '$module' contains the following XS methods:\n\n",
+ $banner, sep(length($banner)),
+ map( { sprintf $format, $_->[0], $_->[1]||'???'}
+ @{ $modules->{$module} }),
+ sep(length($banner)));
+
+ return ($hint, @methods);
+}
+
+# what methods can be invoked on the passed object (or its reference)
+sub lookup_object {
+ my ($object) = shift;
+
+ unless (defined $object) {
+ my $hint = "no 'object' argument was passed\n";
+ return ($hint);
+ }
+
+ _get_objects() unless $objects;
+
+ # a real object was passed?
+ $object = ref $object || $object;
+
+ unless (exists $objects->{$object}) {
+ my $hint = "don't know anything about objects of type '$object'\n";
+ return ($hint);
+ }
+
+ my @methods;
+ my $max_len = 6;
+ for ( @{ $objects->{$object} } ) {
+ $max_len = length $_->[0] if length $_->[0] > $max_len;
+ push @methods, $_->[0];
+ }
+
+ my $format = "%-${max_len}s %s\n";
+ my $banner = sprintf($format, "Method", "Module");
+ my $hint = join '',
+ ("\nObjects of type '$object' can invoke the following XS methods:\n\n",
+ $banner, sep(length($banner)),
+ map({ sprintf $format, $_->[0], $_->[1]} @{ $objects->{$object} }),
+ sep(length($banner)));
+
+ return ($hint, @methods);
+
+}
+
+1;
+EOF
+ close $fh;
+}
+
+sub write_module_versions_file {
+ my $self = shift;
+
+ my $file = catfile "lib", "ModPerl", "DummyVersions.pm";
+ debug "creating $file";
+ open my $fh, ">$file" or die "Can't open $file: $!";
+
+ my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash();
+ print $fh "$noedit_warning\n";
+
+ my @modules = keys %{ $self->{XS} };
+ push @modules, qw(ModPerl::MethodLookup);
+
+ my $len = 0;
+ for (@modules) {
+ $len = length $_ if length $_ > $len;
+ }
+
+ require mod_perl2;
+ $len += length '$::VERSION';
+ for (sort @modules) {
+ my $ver = module_version($_);
+ printf $fh "package %s;\n%-${len}s = %s;\n\n",
+ $_, '$'.$_."::VERSION", $ver;
+ }
+}
+
+sub generate {
+ my $self = shift;
+
+ $self->prepare;
+
+ for (qw(ModPerl::WrapXS Apache2 APR ModPerl)) {
+ $self->write_makefilepl($_);
+ }
+
+ $self->write_typemap;
+
+ for (qw(typedefs sv_convert)) {
+ $self->write_typemap_h_file($_);
+ }
+
+ $self->get_functions;
+ $self->get_structures;
+ $self->write_export_file('exp') if Apache2::Build::AIX;
+ $self->write_export_file('def') if Apache2::Build::WIN32;
+
+ foreach my $module (sort keys %{ $self->{XS} }) {
+ my $functions = $self->{XS}->{$module};
+# my ($root, $sub) = split '::', $module;
+# if (-e "$self->{XS_DIR}/$root/$sub/$sub.xs") {
+# $module = join '::', $root, "Wrap$sub";
+# }
+ $self->write_makefilepl($module);
+ $self->write_xs($module, $functions);
+ $self->write_pm($module);
+ }
+
+ $self->write_lookup_method_file;
+ $self->write_module_versions_file;
+}
+
+#three .sym files are generated:
+#global - global symbols
+#ithreads - #ifdef USE_ITHREADS functions
+#inline - __inline__ functions
+#the inline symbols are needed #ifdef MP_DEBUG
+#since __inline__ will be turned off
+
+my %multi_export = map { $_, 1 } qw(exp);
+
+sub open_export_files {
+ my ($self, $name, $ext) = @_;
+
+ my $dir = $self->{XS_DIR};
+ my %handles;
+ my @types = qw(global inline ithreads);
+
+ if ($multi_export{$ext}) {
+ #write to multiple files
+ for my $type (@types) {
+ my $file = "$dir/${name}_$type.$ext";
+
+ open my $fh, '>', $file or
+ die "open $file: $!";
+
+ $handles{$type} = $fh;
+ }
+ }
+ else {
+ #write to one file
+ my $file = "$dir/$name.$ext";
+
+ open my $fh, '>', $file or
+ die "open $file: $!";
+
+ for my $type (@types) {
+ $handles{$type} = $fh;
+ }
+ }
+
+ \%handles;
+}
+
+sub func_is_static {
+ my ($self, $entry) = @_;
+ if (my $attr = $entry->{attr}) {
+ return 1 if grep { $_ eq 'static' } @$attr;
+ }
+
+ #C::Scan doesnt always pickup static __inline__
+ return 1 if $entry->{name} =~ /^mpxs_/o;
+
+ return 0;
+}
+
+sub func_is_inline {
+ my ($self, $entry) = @_;
+ if (my $attr = $entry->{attr}) {
+ return 1 if grep { $_ eq '__inline__' } @$attr;
+ }
+ return 0;
+}
+
+sub export_file_header_exp {
+ my $self = shift;
+ "#!\n";
+}
+
+sub export_file_format_exp {
+ my ($self, $val) = @_;
+ "$val\n";
+}
+
+sub export_file_header_def {
+ my $self = shift;
+ "LIBRARY\n\nEXPORTS\n\n";
+}
+
+sub export_file_format_def {
+ my ($self, $val) = @_;
+ " $val\n";
+}
+
+my $ithreads_exports = join '|', qw{
+modperl_cmd_interp_
+modperl_interp_
+modperl_list_
+modperl_tipool_
+modperl_svptr_table_clone$
+modperl_mgv_require_module$
+};
+
+sub export_func_handle {
+ my ($self, $entry, $handles) = @_;
+
+ if ($self->func_is_inline($entry)) {
+ return $handles->{inline};
+ }
+ elsif ($entry->{name} =~ /^($ithreads_exports)/) {
+ return $handles->{ithreads};
+ }
+
+ $handles->{global};
+}
+
+sub write_export_file {
+ my ($self, $ext) = @_;
+
+ my %files = (
+ modperl => $ModPerl::FunctionTable,
+ apache2 => $Apache2::FunctionTable,
+ apr => $APR::FunctionTable,
+ );
+
+ my $header = \&{"export_file_header_$ext"};
+ my $format = \&{"export_file_format_$ext"};
+
+ foreach my $key (sort keys %files) {
+ my $table = $files{$key};
+ my $handles = $self->open_export_files($key, $ext);
+
+ my %seen; #only write header once if this is a single file
+ for my $fh (values %$handles) {
+ next if $seen{$fh}++;
+ print $fh $self->$header();
+ }
+
+ # add the symbols which aren't the function table
+ if ($key eq 'modperl') {
+ my $fh = $handles->{global};
+ for my $name (@global_structs) {
+ print $fh $self->$format($name);
+ }
+ }
+
+ for my $entry (@$table) {
+ next if $self->func_is_static($entry);
+ my $name = $entry->{name};
+
+ my $fh = $self->export_func_handle($entry, $handles);
+
+ print $fh $self->$format($name);
+ }
+
+ %seen = (); #only close handle once if this is a single file
+ for my $fh (values %$handles) {
+ next if $seen{$fh}++;
+ close $fh;
+ }
+ }
+}
+
+sub stats {
+ my $self = shift;
+
+ $self->get_functions;
+ $self->get_structures;
+
+ my %stats;
+
+ while (my ($module, $functions) = each %{ $self->{XS} }) {
+ $stats{$module} += @$functions;
+ if (my $newxs = $self->{newXS}->{$module}) {
+ $stats{$module} += @$newxs;
+ }
+ }
+
+ return \%stats;
+}
+
+sub generate_exports {
+ my ($self, $fh) = @_;
+
+ if (!$build->should_build_apache) {
+ print $fh <<"EOF";
+/* This is intentionnaly left blank, only usefull for static build */
+const void *modperl_ugly_hack = NULL;
+EOF
+ return;
+ }
+
+ print $fh <<"EOF";
+/*
+ * This is indeed a ugly hack!
+ * See also src/modules/perl/mod_perl.c for modperl_ugly_hack
+ * If we don't build such a list of exported API functions, the over-zealous
+ * linker can and will remove the unused functions completely. In order to
+ * avoid this, we create this object and modperl_ugly_hack to create a
+ * dependency between all the exported API and mod_perl.c
+ */
+const void *modperl_ugly_hack = NULL;
+EOF
+
+ for my $entry (@$ModPerl::FunctionTable) {
+ next if $self->func_is_static($entry);
+ unless (Apache2::Build::PERL_HAS_ITHREADS) {
+ next if $entry->{name} =~ /^($ithreads_exports)/;
+ }
+ ( my $name ) = $entry->{name} =~ /^modperl_(.*)/;
+ print $fh <<"EOF";
+#ifndef modperl_$name
+const void *modperl_hack_$name = (const void *)modperl_$name;
+#endif
+
+EOF
+ }
+}
+
+1;
+__END__
diff --git a/2_0_13/lib/mod_perl2.pm b/2_0_13/lib/mod_perl2.pm
new file mode 100644
index 0000000..b100fe7
--- /dev/null
+++ b/2_0_13/lib/mod_perl2.pm
@@ -0,0 +1,61 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package mod_perl2;
+
+use 5.006;
+use strict;
+
+BEGIN {
+ our $VERSION = "2.000013";
+ our $VERSION_TRIPLET;
+
+ if ($VERSION =~ /(\d+)\.(\d\d\d)(\d+)/) {
+ my $v1 = $1;
+ my $v2 = int $2;
+ my $v3 = int($3 . "0" x (3 - length $3));
+ $VERSION_TRIPLET = "$v1.$v2.$v3";
+ }
+ else {
+ die "bad version: $VERSION";
+ }
+
+ # for example this gives us:
+ # $VERSION : "2.000020"
+ # int $VERSION : 2.00002
+ # $VERSION_TRIPLET: 2.0.20
+
+ # easy to parse request time API version - use
+ # $mod_perl2::VERSION for more granularity
+ our $API_VERSION = 2;
+}
+
+# this stuff is here to assist back compat
+# basically, if you
+# PerlModule mod_perl2
+# or take similar steps to load mod_perl2 at
+# startup you are protected against loading mod_perl.pm
+# (either 1.0 or 1.99) at a later time by accident.
+$mod_perl::VERSION = $mod_perl2::VERSION;
+$INC{"mod_perl.pm"} = __FILE__;
+
+1;
+__END__
+
+=head1 NAME
+
+mod_perl - Embed a Perl interpreter in the Apache/2.x HTTP server
+
diff --git a/2_0_13/patches/c-scan.pat b/2_0_13/patches/c-scan.pat
new file mode 100644
index 0000000..08efb55
--- /dev/null
+++ b/2_0_13/patches/c-scan.pat
@@ -0,0 +1,16 @@
+--- Scan.pm~ Thu Mar 23 06:14:18 2000
++++ Scan.pm Sun Jan 7 11:56:04 2001
+@@ -400,7 +400,12 @@
+ } else {
+ $vars = parse_vars($chunk);
+ }
+- push @$struct, @$vars;
++ if ($vars) {
++ push @$struct, @$vars;
++ }
++ else {
++ warn "unable to parse chunk: `$chunk'" if $C::Scan::Warn;
++ }
+ }
+ $structs->{$structname} = $struct;
+ $structname;
diff --git a/2_0_13/patches/link-hack.pat b/2_0_13/patches/link-hack.pat
new file mode 100644
index 0000000..cf7e757
--- /dev/null
+++ b/2_0_13/patches/link-hack.pat
@@ -0,0 +1,46 @@
+Index: src/build/program.mk
+===================================================================
+RCS file: /home/cvs/apache-2.0/src/build/program.mk,v
+retrieving revision 1.3
+diff -u -u -r1.3 program.mk
+--- src/build/program.mk 2000/03/31 07:02:31 1.3
++++ src/build/program.mk 2000/04/16 23:43:14
+@@ -54,7 +54,10 @@
+ # The build environment was provided by Sascha Schumann.
+ #
+
++MP_SRC = ../../modperl-2.0/src/modules/perl
++MP_LDADD = $(MP_SRC)/libmodperl.a `$(MP_SRC)/ldopts`
++
+ PROGRAM_OBJECTS = $(PROGRAM_SOURCES:.c=.lo)
+
+ $(PROGRAM_NAME): $(PROGRAM_DEPENDENCIES) $(PROGRAM_OBJECTS)
+- $(LINK) $(PROGRAM_LDFLAGS) $(PROGRAM_OBJECTS) $(PROGRAM_LDADD)
++ $(LINK) $(PROGRAM_LDFLAGS) $(PROGRAM_OBJECTS) $(PROGRAM_LDADD) $(MP_LDADD)
+
+--- src/modules.c~ Wed Apr 12 20:00:23 2000
++++ src/modules.c Wed Apr 12 20:10:16 2000
+@@ -26,6 +26,7 @@
+ extern module auth_module;
+ extern module setenvif_module;
+ extern module echo_module;
++extern module perl_module;
+
+ /*
+ * Modules which implicitly form the
+@@ -54,6 +55,7 @@
+ &auth_module,
+ &setenvif_module,
+ &echo_module,
++ &perl_module,
+ NULL
+ };
+
+@@ -84,6 +86,7 @@
+ &auth_module,
+ &setenvif_module,
+ &echo_module,
++ &perl_module,
+ NULL
+ };
+
diff --git a/2_0_13/src/modules/perl/mod_perl.c b/2_0_13/src/modules/perl/mod_perl.c
new file mode 100644
index 0000000..4edba4a
--- /dev/null
+++ b/2_0_13/src/modules/perl/mod_perl.c
@@ -0,0 +1,1149 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* make sure that mod_perl won't try to start itself, while it's
+ * already starting. If the flag's value is 1 * it's still starting,
+ * when it's 2 it is running */
+static int MP_init_status = 0;
+
+#define MP_IS_NOT_RUNNING (MP_init_status == 0 ? 1 : 0)
+#define MP_IS_STARTING (MP_init_status == 1 ? 1 : 0)
+#define MP_IS_RUNNING (MP_init_status == 2 ? 1 : 0)
+
+/* false while there is only the parent process and may be child
+ * processes, but no threads around, useful for allowing things that
+ * don't require locking and won't affect other threads. It should
+ * become true just before the child_init phase */
+static int MP_threads_started = 0;
+
+int modperl_threads_started(void)
+{
+ return MP_threads_started;
+}
+
+static int MP_threaded_mpm = 0;
+
+int modperl_threaded_mpm(void)
+{
+ return MP_threaded_mpm;
+}
+
+/* sometimes non-threaded mpm also needs to know whether it's still
+ * starting up or after post_config) */
+static int MP_post_post_config_phase = 0;
+
+int modperl_post_post_config_phase(void)
+{
+ return MP_post_post_config_phase;
+}
+
+#ifndef USE_ITHREADS
+static apr_status_t modperl_shutdown(void *data)
+{
+ modperl_cleanup_data_t *cdata = (modperl_cleanup_data_t *)data;
+ PerlInterpreter *perl = (PerlInterpreter *)cdata->data;
+ void **handles;
+
+ handles = modperl_xs_dl_handles_get(aTHX);
+
+ MP_TRACE_i(MP_FUNC, "destroying interpreter=0x%lx",
+ (unsigned long)perl);
+
+ modperl_perl_destruct(perl);
+
+ modperl_xs_dl_handles_close(handles);
+
+ return APR_SUCCESS;
+}
+#endif
+
+static const char *MP_xs_loaders[] = {
+ "Apache2", "APR", NULL,
+};
+
+#define MP_xs_loader_name "%s::XSLoader::BOOTSTRAP"
+
+/* ugly hack to have access to startup pool and server during xs_init */
+static struct {
+ apr_pool_t *p;
+ server_rec *s;
+} MP_boot_data = {NULL,NULL};
+
+#define MP_boot_data_set(pool, server) \
+ MP_boot_data.p = pool; \
+ MP_boot_data.s = server
+
+#define MP_dBOOT_DATA \
+ apr_pool_t *p = MP_boot_data.p; \
+ server_rec *s = MP_boot_data.s
+
+static void modperl_boot(pTHX_ void *data)
+{
+ MP_dBOOT_DATA;
+ int i;
+
+ modperl_env_clear(aTHX);
+
+ modperl_env_default_populate(aTHX);
+
+ modperl_env_configure_server(aTHX_ p, s);
+
+ modperl_perl_core_global_init(aTHX);
+
+ for (i=0; MP_xs_loaders[i]; i++) {
+ char *name = Perl_form(aTHX_ MP_xs_loader_name, MP_xs_loaders[i]);
+ newCONSTSUB(PL_defstash, name, newSViv(1));
+ }
+
+ /* outside mod_perl this is done by ModPerl::Const.xs */
+ newXS("ModPerl::Const::compile", XS_modperl_const_compile, __FILE__);
+
+ /* make sure DynaLoader is loaded before XSLoader
+ * - to workaround bug in 5.6.1 that can trigger a segv
+ * when using modperl as a dso
+ * - also needed when <Perl> sections are loaded from +Parent vhost
+ */
+ modperl_require_module(aTHX_ "DynaLoader", FALSE);
+
+ IoFLUSH_on(PL_stderrgv); /* unbuffer STDERR */
+}
+
+static void modperl_xs_init(pTHX)
+{
+ xs_init(aTHX); /* see modperl_xsinit.c */
+
+ /* XXX: in 5.7.2+ we can call the body of modperl_boot here
+ * but in 5.6.1 the Perl runtime is not properly setup yet
+ * so we have to pull this stunt to delay
+ */
+ SAVEDESTRUCTOR_X(modperl_boot, 0);
+}
+
+/*
+ * the "server_pool" is a subpool of the parent pool (aka "pconf")
+ * this is where we register the cleanups that teardown the interpreter.
+ * the parent process will run the cleanups since server_pool is a subpool
+ * of pconf. we manually clear the server_pool to run cleanups in the
+ * child processes
+ *
+ * the "server_user_pool" is a subpool of the "server_pool", this is
+ * the pool which is exposed to users, so that they can register
+ * cleanup callbacks. This is needed so that the perl cleanups won't
+ * be run before user cleanups are executed.
+ *
+ */
+static apr_pool_t *server_pool = NULL;
+static apr_pool_t *server_user_pool = NULL;
+
+apr_pool_t *modperl_server_pool(void)
+{
+ return server_pool;
+}
+
+apr_pool_t *modperl_server_user_pool(void)
+{
+ return server_user_pool;
+}
+
+static void set_taint_var(PerlInterpreter *perl)
+{
+ dTHXa(perl);
+
+/* 5.7.3+ has a built-in special ${^TAINT}, backport it to 5.6.0+ */
+#if MP_PERL_VERSION_AT_MOST(5, 7, 2)
+ {
+ GV *gv = gv_fetchpv("\024AINT", GV_ADDMULTI, SVt_IV);
+ sv_setiv(GvSV(gv), PL_tainting);
+ SvREADONLY_on(GvSV(gv));
+ }
+#endif /* perl v < 5.7.3 */
+
+#ifdef MP_COMPAT_1X
+ {
+ GV *gv = gv_fetchpv("Apache2::__T", GV_ADDMULTI, SVt_PV);
+ sv_setiv(GvSV(gv), PL_tainting);
+ SvREADONLY_on(GvSV(gv));
+ }
+#endif /* MP_COMPAT_1X */
+
+}
+
+PerlInterpreter *modperl_startup(server_rec *s, apr_pool_t *p)
+{
+ AV *endav;
+ dTHXa(NULL);
+ MP_dSCFG(s);
+ PerlInterpreter *perl;
+ int status;
+ char **argv;
+ int argc;
+#ifndef USE_ITHREADS
+ modperl_cleanup_data_t *cdata;
+#endif
+
+ /* ensure that we start the base server's perl, before vhost's
+ * one, if modperl_startup was called by vhost before the former
+ * was started */
+ if (MP_init_status != 2) {
+ server_rec *base_server = modperl_global_get_server_rec();
+ PerlInterpreter *base_perl;
+
+ MP_init_status = 2; /* calls itself, so set the flag early */
+ base_perl = modperl_startup(base_server, p);
+
+ if (base_server == s ) {
+ return base_perl;
+ }
+ }
+
+#ifdef MP_TRACE
+ {
+ server_rec *base_server = modperl_global_get_server_rec();
+ const char *desc = modperl_server_desc(s, p);
+ if (base_server == s) {
+ MP_init_status = 1; /* temporarily reset MP_init_status */
+ MP_TRACE_i(MP_FUNC,
+ "starting the parent perl for the base server", desc);
+ MP_init_status = 2;
+ }
+ else {
+ MP_TRACE_i(MP_FUNC,
+ "starting the parent perl for vhost %s", desc);
+ }
+ }
+#endif
+
+#ifdef MP_USE_GTOP
+ MP_TRACE_m_do(
+ modperl_gtop_do_proc_mem_before(MP_FUNC, "perl_parse");
+ );
+#endif
+
+ argv = modperl_config_srv_argv_init(scfg, &argc);
+
+ if (!(perl = perl_alloc())) {
+ perror("perl_alloc");
+ exit(1);
+ }
+
+#ifdef USE_ITHREADS
+ aTHX = perl;
+#endif
+
+ perl_construct(perl);
+
+ modperl_hash_seed_set(aTHX);
+
+ modperl_io_apache_init(aTHX);
+
+ PL_perl_destruct_level = 2;
+
+ MP_boot_data_set(p, s);
+ status = perl_parse(perl, modperl_xs_init, argc, argv, NULL);
+ MP_boot_data_set(NULL, NULL);
+
+ if (status) {
+ perror("perl_parse");
+ exit(1);
+ }
+
+ modperl_env_init(aTHX);
+
+ /* suspend END blocks to be run at server shutdown */
+ endav = PL_endav;
+ PL_endav = (AV *)NULL;
+
+/* This was fixed in 5.9.0/5.8.1 (17775), but won't compile after 19122 */
+#if MP_PERL_VERSION(5, 8, 0) && \
+ defined(USE_REENTRANT_API) && defined(HAS_CRYPT_R) && defined(__GLIBC__)
+ /* workaround perl5.8.0/glibc bug */
+ PL_reentrant_buffer->_crypt_struct.current_saltbits = 0;
+#endif
+
+ /* We need to reset $0 to argv[0] (httpd) since perl_parse() will
+ * have set it to '-e'. Being magic-aware ensures that some
+ * OS-specific magic will happen (i.e. setproctitle() on *BSDs)
+ */
+ PL_origalen = strlen(argv[0]) + 1;
+ sv_setpv_mg(get_sv("0",0), argv[0]);
+
+ perl_run(perl);
+
+#ifdef USE_ITHREADS
+ /* base server / virtual host w/ +Parent gets its own mip */
+ modperl_interp_init(s, p, perl);
+
+ /* mark the parent perl to be destroyed */
+ MpInterpBASE_On(scfg->mip->parent);
+#endif
+
+ PL_endav = endav;
+
+ set_taint_var(perl);
+
+ MP_TRACE_i(MP_FUNC, "constructed interpreter=0x%lx",
+ (unsigned long)perl);
+
+#ifdef MP_USE_GTOP
+ MP_TRACE_m_do(
+ modperl_gtop_do_proc_mem_after(MP_FUNC, "perl_parse");
+ );
+#endif
+
+#ifdef MP_COMPAT_1X
+ {
+ char *path, *path1;
+ apr_finfo_t finfo;
+ /* 1) push @INC, $ServerRoot */
+ av_push(GvAV(PL_incgv), newSVpv(ap_server_root, 0));
+
+ /* 2) push @INC, $ServerRoot/lib/perl only if it exists */
+ apr_filepath_merge(&path, ap_server_root, "lib",
+ APR_FILEPATH_NATIVE, p);
+ apr_filepath_merge(&path1, path, "perl",
+ APR_FILEPATH_NATIVE, p);
+ if (APR_SUCCESS == apr_stat(&finfo, path1, APR_FINFO_TYPE, p)) {
+ if (finfo.filetype == APR_DIR) {
+ av_push(GvAV(PL_incgv), newSVpv(path1, 0));
+ }
+ }
+ }
+#endif /* MP_COMPAT_1X */
+
+ /* base perl and each vhost +Parent should have this init'ed */
+ modperl_handler_anon_init(aTHX_ p);
+
+ if (!modperl_config_apply_PerlRequire(s, scfg, perl, p)) {
+ exit(1);
+ }
+
+ if (!modperl_config_apply_PerlModule(s, scfg, perl, p)) {
+ exit(1);
+ }
+
+#ifndef USE_ITHREADS
+ cdata = modperl_cleanup_data_new(server_pool, (void*)perl);
+ apr_pool_cleanup_register(server_pool, cdata,
+ modperl_shutdown, apr_pool_cleanup_null);
+#endif
+
+ return perl;
+}
+
+int modperl_init_vhost(server_rec *s, apr_pool_t *p,
+ server_rec *base_server)
+{
+ MP_dSCFG(s);
+ modperl_config_srv_t *base_scfg;
+ PerlInterpreter *base_perl;
+ PerlInterpreter *perl;
+ const char *vhost = modperl_server_desc(s, p);
+
+ if (!scfg) {
+ MP_TRACE_i(MP_FUNC, "server %s has no mod_perl config", vhost);
+ return OK;
+ }
+
+ if (base_server == NULL) {
+ base_server = modperl_global_get_server_rec();
+ }
+
+ MP_TRACE_i(MP_FUNC, "Init vhost %s: s=0x%lx, base_s=0x%lx",
+ vhost, s, base_server);
+
+ if (base_server == s) {
+ MP_TRACE_i(MP_FUNC, "base server is not vhost, skipping %s",
+ vhost);
+ return OK;
+ }
+
+ base_scfg = modperl_config_srv_get(base_server);
+
+#ifdef USE_ITHREADS
+ perl = base_perl = base_scfg->mip->parent->perl;
+#else
+ perl = base_perl = base_scfg->perl;
+#endif /* USE_ITHREADS */
+
+#ifdef USE_ITHREADS
+
+ if (scfg->mip) {
+ MP_TRACE_i(MP_FUNC, "server %s already initialized", vhost);
+ return OK;
+ }
+
+ /* the base server could have mod_perl callbacks disabled, but it
+ * still needs perl to drive the vhosts */
+ if (!MpSrvENABLE(scfg) && s->is_virtual) {
+ MP_TRACE_i(MP_FUNC, "mod_perl disabled for server %s", vhost);
+ scfg->mip = NULL;
+ return OK;
+ }
+
+ PERL_SET_CONTEXT(perl);
+ modperl_thx_interp_set(perl, base_scfg->mip->parent);
+
+#endif /* USE_ITHREADS */
+
+ MP_TRACE_d_do(MpSrv_dump_flags(scfg, s->server_hostname));
+
+ /* if alloc flags is On, virtual host gets its own parent perl */
+ if (MpSrvPARENT(scfg)) {
+ perl = modperl_startup(s, p);
+ MP_TRACE_i(MP_FUNC,
+ "created parent interpreter for VirtualHost %s",
+ modperl_server_desc(s, p));
+ }
+ else {
+#ifdef USE_ITHREADS
+ /* virtual host w/ +Clone gets its own mip */
+ if (MpSrvCLONE(scfg)) {
+ modperl_interp_init(s, p, perl);
+ }
+#endif
+
+ if (!modperl_config_apply_PerlRequire(s, scfg, perl, p)) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (!modperl_config_apply_PerlModule(s, scfg, perl, p)) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+#ifdef USE_ITHREADS
+ if (!scfg->mip) {
+ /* since mips are created after merge_server_configs()
+ * need to point to the base mip here if this vhost
+ * doesn't have its own
+ */
+ MP_TRACE_i(MP_FUNC, "%s mip inherited from %s",
+ vhost, modperl_server_desc(base_server, p));
+ scfg->mip = base_scfg->mip;
+ }
+#endif /* USE_ITHREADS */
+
+ return OK;
+}
+
+void modperl_init(server_rec *base_server, apr_pool_t *p)
+{
+ server_rec *s;
+ PerlInterpreter *base_perl;
+#if defined(MP_TRACE) || defined(USE_ITHREADS)
+ modperl_config_srv_t *base_scfg = modperl_config_srv_get(base_server);
+#endif
+
+ MP_TRACE_d_do(MpSrv_dump_flags(base_scfg,
+ base_server->server_hostname));
+
+#ifndef USE_ITHREADS
+ if (modperl_threaded_mpm()) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server,
+ "cannot use threaded MPM without ithreads enabled Perl");
+ exit(1);
+ }
+#endif
+
+ base_perl = modperl_startup(base_server, p);
+
+ for (s=base_server->next; s; s=s->next) {
+ if (modperl_init_vhost(s, p, base_server) != OK) {
+ exit(1); /*XXX*/
+ }
+ }
+
+#ifdef USE_ITHREADS
+ /* after other parent perls were started in vhosts, make sure that
+ * the context is set to the base_perl */
+ PERL_SET_CONTEXT(base_perl);
+ modperl_thx_interp_set(base_perl, base_scfg->mip->parent);
+#endif
+
+}
+
+static int modperl_post_config_require(server_rec *s, apr_pool_t *p)
+{
+ for (; s; s=s->next) {
+ MP_dSCFG(s);
+ if (!modperl_config_apply_PerlPostConfigRequire(s, scfg, p)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+#ifdef USE_ITHREADS
+static void modperl_init_clones(server_rec *s, apr_pool_t *p)
+{
+#ifdef MP_TRACE
+ modperl_config_srv_t *base_scfg = modperl_config_srv_get(s);
+ char *base_name = modperl_server_desc(s, p);
+#endif /* MP_TRACE */
+
+ if (!modperl_threaded_mpm()) {
+ MP_TRACE_i(MP_FUNC, "no clones created for non-threaded mpm");
+ return;
+ }
+
+ for (; s; s=s->next) {
+ MP_dSCFG(s);
+#ifdef MP_TRACE
+ char *name = modperl_server_desc(s, p);
+#else
+ char *name = NULL;
+#endif /* MP_TRACE */
+
+ if (scfg->mip->tipool->idle) {
+#ifdef MP_TRACE
+ if (scfg->mip == base_scfg->mip) {
+ MP_TRACE_i(MP_FUNC,
+ "%s interp pool inherited from %s",
+ name, base_name);
+ }
+ else {
+ MP_TRACE_i(MP_FUNC,
+ "%s interp pool already initialized",
+ name);
+ }
+#endif /* MP_TRACE */
+ }
+ else {
+ MP_TRACE_i(MP_FUNC, "initializing interp pool for %s",
+ name);
+ modperl_tipool_init(scfg->mip->tipool);
+ }
+ }
+}
+#endif /* USE_ITHREADS */
+
+void modperl_init_globals(server_rec *s, apr_pool_t *pconf)
+{
+ ap_mpm_query(AP_MPMQ_IS_THREADED, &MP_threaded_mpm);
+
+ MP_TRACE_g(MP_FUNC, "mod_perl globals are configured");
+
+ modperl_global_init_pconf(pconf, pconf);
+ modperl_global_init_server_rec(pconf, s);
+
+ modperl_tls_create_request_rec(pconf);
+
+ /* init the counter to 0 */
+ modperl_global_anon_cnt_init(pconf);
+}
+
+/*
+ * modperl_sys_{init,term} are things that happen
+ * once per-parent process, not per-interpreter
+ */
+static apr_status_t modperl_sys_init(void)
+{
+ int argc = 0;
+ char **argv = NULL, **env = NULL;
+
+ MP_TRACE_i(MP_FUNC, "mod_perl sys init");
+
+ /* not every OS uses those vars in PERL_SYS_INIT3 macro */
+ argc = argc; argv = argv; env = env;
+
+ PERL_SYS_INIT3(&argc, &argv, &env);
+
+#if 0 /*XXX*/
+#ifdef PTHREAD_ATFORK
+ if (!ap_exists_config_define("PERL_PTHREAD_ATFORK_DONE")) {
+ PTHREAD_ATFORK(Perl_atfork_lock,
+ Perl_atfork_unlock,
+ Perl_atfork_unlock);
+ *(char **)apr_array_push(ap_server_config_defines) =
+ "PERL_PTHREAD_ATFORK_DONE";
+ }
+#endif
+#endif
+
+ /* modifies PL_ppaddr */
+ modperl_perl_pp_set_all();
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t modperl_sys_term(void *data)
+{
+ /* PERL_SYS_TERM() needs 'my_perl' as of 5.9.5 */
+#if MP_PERL_VERSION_AT_LEAST(5, 9, 5) && defined(USE_ITHREADS)
+ modperl_cleanup_data_t *cdata = (modperl_cleanup_data_t *)data;
+ PERL_UNUSED_DECL PerlInterpreter *my_perl = cdata == NULL ? NULL : (PerlInterpreter *)cdata->data;
+#endif
+ MP_init_status = 0;
+ MP_threads_started = 0;
+ MP_post_post_config_phase = 0;
+
+ MP_PERL_FREE_THREAD_KEY_WORKAROUND;
+
+ MP_TRACE_i(MP_FUNC, "mod_perl sys term");
+
+ modperl_perl_pp_unset_all();
+
+ PERL_SYS_TERM();
+
+ return APR_SUCCESS;
+}
+
+int modperl_hook_init(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ if (MP_IS_STARTING || MP_IS_RUNNING) {
+ return OK;
+ }
+
+ MP_init_status = 1; /* now starting */
+
+ modperl_restart_count_inc(s);
+
+ apr_pool_create(&server_pool, pconf);
+ apr_pool_tag(server_pool, "mod_perl server pool");
+
+ apr_pool_create(&server_user_pool, pconf);
+ apr_pool_tag(server_user_pool, "mod_perl server user pool");
+
+ modperl_sys_init();
+ apr_pool_cleanup_register(server_pool, NULL,
+ modperl_sys_term, apr_pool_cleanup_null);
+
+ modperl_init(s, pconf);
+
+ return OK;
+}
+
+/*
+ * if we need to init earlier than post_config,
+ * e.g. <Perl> sections or directive handlers.
+ */
+int modperl_run(void)
+{
+ return modperl_hook_init(modperl_global_get_pconf(),
+ NULL,
+ NULL,
+ modperl_global_get_server_rec());
+}
+
+int modperl_is_running(void)
+{
+ return MP_IS_RUNNING;
+}
+
+int modperl_hook_pre_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+#if AP_MODULE_MAGIC_AT_LEAST(20110329,0)
+ ap_reserve_module_slots_directive("PerlLoadModule");
+#endif
+
+ /* we can't have PerlPreConfigHandler without first configuring mod_perl */
+
+ /* perl 5.8.1+ */
+ modperl_hash_seed_init(p);
+
+ return OK;
+}
+
+static int modperl_hook_pre_connection(conn_rec *c, void *csd)
+{
+ modperl_input_filter_add_connection(c);
+ modperl_output_filter_add_connection(c);
+ return OK;
+}
+
+static int modperl_hook_post_config_last(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ /* in the threaded environment, no server_rec/process_rec
+ * modifications should be done beyond this point */
+#ifdef USE_ITHREADS
+ MP_dSCFG(s);
+ dTHXa(scfg->mip->parent->perl);
+#endif
+
+ if (!modperl_post_config_require(s, pconf)) {
+ exit(1);
+ }
+
+ if (modperl_threaded_mpm()) {
+ MP_threads_started = 1;
+ }
+
+ MP_post_post_config_phase = 1;
+
+#ifdef MP_TRACE
+ /* httpd core open_logs handler re-opens s->error_log, which might
+ * change, even though it still points to the same physical file
+ * (.e.g on win32 the filehandle will be different. Therefore
+ * reset the tracing logfile setting here, since this is the
+ * earliest place, happening after the open_logs phase.
+ *
+ * Moreover, we need to dup the filehandle so that when the server
+ * shuts down, we will be able to log to error_log after Apache
+ * has closed it (which happens too early for our likening).
+ */
+ {
+ apr_file_t *dup;
+ MP_RUN_CROAK(apr_file_dup(&dup, s->error_log, pconf),
+ "mod_perl core post_config");
+ modperl_trace_logfile_set(dup);
+ }
+#endif
+
+#if MP_PERL_VERSION_AT_LEAST(5, 9, 0)
+#define MP_PERL_VERSION_STAMP "Perl/%" SVf
+#else
+#define MP_PERL_VERSION_STAMP "Perl/v%vd"
+#endif
+
+ ap_add_version_component(pconf, MP_VERSION_STRING);
+ ap_add_version_component(pconf,
+ Perl_form(aTHX_ MP_PERL_VERSION_STAMP,
+ PL_patchlevel));
+
+ modperl_mgv_hash_handlers(pconf, s);
+ modperl_modglobal_hash_keys(aTHX);
+ modperl_env_hash_keys(aTHX);
+#ifdef USE_ITHREADS
+ modperl_init_clones(s, pconf);
+#endif
+
+#ifdef MP_NEED_HASH_SEED_FIXUP
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ "mod_perl: using Perl HASH_SEED: %"UVuf, MP_init_hash_seed);
+#endif
+
+ return OK;
+}
+
+static int modperl_hook_create_request(request_rec *r)
+{
+ MP_dRCFG;
+
+#ifdef USE_ITHREADS
+ /* XXX: this is necessary to make modperl_interp_pool_select() work
+ * which is used at runtime only to merge dir-configs by
+ * modperl_module_config_merge().
+ *
+ * Since most requests won't need it it would be good to add some logic
+ * (cheaper logic in terms of CPU cycles) to identify those cases and
+ * avoid the hash operation.
+ */
+ MP_TRACE_i(MP_FUNC, "setting userdata MODPERL_R in pool %#lx to %lx",
+ (unsigned long)r->pool, (unsigned long)r);
+ (void)apr_pool_userdata_set((void *)r, "MODPERL_R", NULL, r->pool);
+#endif
+
+ modperl_config_req_init(r, rcfg);
+ modperl_config_req_cleanup_register(r, rcfg);
+
+ /* set the default for cgi header parsing On as early as possible
+ * so $r->content_type in any phase after header_parser could turn
+ * it off. wb->header_parse will be set to 1 only if this flag
+ * wasn't turned off and MpDirPARSE_HEADERS is on
+ */
+ MpReqPARSE_HEADERS_On(rcfg);
+
+ return OK;
+}
+
+static int modperl_hook_post_read_request(request_rec *r)
+{
+#ifdef USE_ITHREADS
+ MP_TRACE_i(MP_FUNC, "%s %s:%d%s",
+ r->method, r->connection->local_addr->hostname,
+ r->connection->local_addr->port, r->unparsed_uri);
+#endif
+
+ /* if 'PerlOptions +GlobalRequest' is outside a container */
+ modperl_global_request_cfg_set(r);
+
+ return OK;
+}
+
+static int modperl_hook_header_parser(request_rec *r)
+{
+ /* if 'PerlOptions +GlobalRequest' is inside a container */
+ modperl_global_request_cfg_set(r);
+
+ return OK;
+}
+
+static int modperl_destruct_level = 2; /* default is full tear down */
+
+int modperl_perl_destruct_level(void)
+{
+ return modperl_destruct_level;
+}
+
+#ifdef USE_ITHREADS
+
+static apr_status_t
+modperl_perl_call_endav_mip(pTHX_ modperl_interp_pool_t *mip,
+ void *data)
+{
+ modperl_perl_call_endav(aTHX);
+ return APR_SUCCESS;
+}
+
+#endif /* USE_ITHREADS */
+
+static apr_status_t modperl_child_exit(void *data)
+{
+ char *level = NULL;
+ server_rec *s = (server_rec *)data;
+
+ modperl_callback_process(MP_CHILD_EXIT_HANDLER, server_pool, s,
+ MP_HOOK_VOID);
+
+ if ((level = getenv("PERL_DESTRUCT_LEVEL"))) {
+ modperl_destruct_level = atoi(level);
+ }
+ else {
+ /* default to no teardown in the children */
+ modperl_destruct_level = 0;
+ }
+
+ if (modperl_destruct_level) {
+ apr_pool_clear(server_pool);
+ }
+ else {
+ /* run the END blocks of this child process if
+ * modperl_perl_destruct is not called for this process */
+#ifdef USE_ITHREADS
+ modperl_interp_mip_walk_servers(NULL, s,
+ modperl_perl_call_endav_mip,
+ (void*)NULL);
+#else
+ modperl_perl_call_endav(aTHX);
+#endif
+ }
+
+ server_pool = NULL;
+
+ return APR_SUCCESS;
+}
+
+static void modperl_hook_child_init(apr_pool_t *p, server_rec *s)
+{
+ modperl_perl_init_ids_server(s);
+
+ apr_pool_cleanup_register(p, (void *)s, modperl_child_exit,
+ apr_pool_cleanup_null);
+}
+
+#define MP_FILTER_HANDLER(f) f, NULL
+
+void modperl_register_hooks(apr_pool_t *p)
+{
+
+#ifdef USE_ITHREADS
+ APR_REGISTER_OPTIONAL_FN(modperl_interp_unselect);
+ APR_REGISTER_OPTIONAL_FN(modperl_thx_interp_get);
+#endif
+
+ /* for <IfDefine MODPERL2> and Apache2->define("MODPERL2") */
+ *(char **)apr_array_push(ap_server_config_defines) =
+ apr_pstrdup(ap_server_config_defines->pool, "MODPERL2");
+
+ ap_hook_pre_config(modperl_hook_pre_config,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_open_logs(modperl_hook_init,
+ NULL, NULL, APR_HOOK_FIRST);
+
+ ap_hook_post_config(modperl_hook_post_config_last,
+ NULL, NULL, APR_HOOK_REALLY_LAST);
+
+ ap_hook_handler(modperl_response_handler,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_handler(modperl_response_handler_cgi,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_insert_filter(modperl_output_filter_add_request,
+ NULL, NULL, APR_HOOK_LAST);
+
+ ap_hook_insert_filter(modperl_input_filter_add_request,
+ NULL, NULL, APR_HOOK_LAST);
+
+ ap_register_output_filter(MP_FILTER_REQUEST_OUTPUT_NAME,
+ MP_FILTER_HANDLER(modperl_output_filter_handler),
+ AP_FTYPE_RESOURCE);
+
+ ap_register_input_filter(MP_FILTER_REQUEST_INPUT_NAME,
+ MP_FILTER_HANDLER(modperl_input_filter_handler),
+ AP_FTYPE_RESOURCE);
+
+ ap_register_output_filter(MP_FILTER_CONNECTION_OUTPUT_NAME,
+ MP_FILTER_HANDLER(modperl_output_filter_handler),
+ AP_FTYPE_CONNECTION);
+
+ ap_register_input_filter(MP_FILTER_CONNECTION_INPUT_NAME,
+ MP_FILTER_HANDLER(modperl_input_filter_handler),
+ AP_FTYPE_CONNECTION);
+
+ ap_hook_pre_connection(modperl_hook_pre_connection,
+ NULL, NULL, APR_HOOK_FIRST);
+
+ ap_hook_create_request(modperl_hook_create_request,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ /* both of these hooks need to run really, really first.
+ * otherwise, the global request_rec will be set up _after_ some
+ * Perl handlers run.
+ */
+ ap_hook_post_read_request(modperl_hook_post_read_request,
+ NULL, NULL, MODPERL_HOOK_REALLY_REALLY_FIRST);
+
+ ap_hook_header_parser(modperl_hook_header_parser,
+ NULL, NULL, MODPERL_HOOK_REALLY_REALLY_FIRST);
+
+ ap_hook_child_init(modperl_hook_child_init,
+ NULL, NULL, MODPERL_HOOK_REALLY_REALLY_FIRST);
+
+ modperl_register_handler_hooks();
+}
+
+static const command_rec modperl_cmds[] = {
+ MP_CMD_SRV_ITERATE("PerlSwitches", switches, "Perl Switches"),
+ MP_CMD_DIR_ITERATE("PerlModule", modules, "PerlModule"),
+ MP_CMD_DIR_ITERATE("PerlRequire", requires, "PerlRequire"),
+ MP_CMD_SRV_ITERATE("PerlConfigRequire", config_requires, "PerlConfigRequire"),
+ MP_CMD_SRV_ITERATE("PerlPostConfigRequire", post_config_requires, "PerlPostConfigRequire"),
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+ MP_CMD_SRV_TAKE2("PerlAddAuthzProvider", authz_provider, "PerlAddAuthzProvider"),
+ MP_CMD_SRV_TAKE2("PerlAddAuthnProvider", authn_provider, "PerlAddAuthnProvider"),
+#endif
+ MP_CMD_DIR_ITERATE("PerlOptions", options, "Perl Options"),
+ MP_CMD_DIR_ITERATE("PerlInitHandler", init_handlers, "Subroutine name"),
+ MP_CMD_DIR_TAKE2("PerlSetVar", set_var, "PerlSetVar"),
+ MP_CMD_DIR_ITERATE2("PerlAddVar", add_var, "PerlAddVar"),
+ MP_CMD_DIR_TAKE2("PerlSetEnv", set_env, "PerlSetEnv"),
+ MP_CMD_SRV_TAKE1("PerlPassEnv", pass_env, "PerlPassEnv"),
+ MP_CMD_SRV_RAW_ARGS_ON_READ("<Perl", perl, "Perl Code"),
+ MP_CMD_SRV_RAW_ARGS("Perl", perldo, "Perl Code"),
+
+ MP_CMD_DIR_TAKE1("PerlSetInputFilter", set_input_filter,
+ "filter[;filter]"),
+ MP_CMD_DIR_TAKE1("PerlSetOutputFilter", set_output_filter,
+ "filter[;filter]"),
+
+ MP_CMD_SRV_RAW_ARGS_ON_READ("=pod", pod, "Start of POD"),
+ MP_CMD_SRV_RAW_ARGS_ON_READ("=back", pod, "End of =over"),
+ MP_CMD_SRV_RAW_ARGS_ON_READ("=cut", pod_cut, "End of POD"),
+ MP_CMD_SRV_RAW_ARGS_ON_READ("__END__", END, "Stop reading config"),
+
+ MP_CMD_SRV_RAW_ARGS("PerlLoadModule", load_module, "A Perl module"),
+#ifdef MP_TRACE
+ MP_CMD_SRV_TAKE1("PerlTrace", trace, "Trace level"),
+#endif
+#ifdef USE_ITHREADS
+ MP_CMD_SRV_TAKE1("PerlInterpStart", interp_start,
+ "Number of Perl interpreters to start"),
+ MP_CMD_SRV_TAKE1("PerlInterpMax", interp_max,
+ "Max number of running Perl interpreters"),
+ MP_CMD_SRV_TAKE1("PerlInterpMaxSpare", interp_max_spare,
+ "Max number of spare Perl interpreters"),
+ MP_CMD_SRV_TAKE1("PerlInterpMinSpare", interp_min_spare,
+ "Min number of spare Perl interpreters"),
+ MP_CMD_SRV_TAKE1("PerlInterpMaxRequests", interp_max_requests,
+ "Max number of requests per Perl interpreters"),
+#endif
+#ifdef MP_COMPAT_1X
+ MP_CMD_DIR_FLAG("PerlSendHeader", send_header,
+ "Tell mod_perl to scan output for HTTP headers"),
+ MP_CMD_DIR_FLAG("PerlSetupEnv", setup_env,
+ "Turn setup of %ENV On or Off"),
+ MP_CMD_DIR_ITERATE("PerlHandler", response_handlers,
+ "Subroutine name"),
+ MP_CMD_SRV_FLAG("PerlTaintCheck", taint_check,
+ "Turn on -T switch"),
+ MP_CMD_SRV_FLAG("PerlWarn", warn,
+ "Turn on -w switch"),
+#endif
+ MP_CMD_ENTRIES,
+ { NULL },
+};
+
+void modperl_response_init(request_rec *r)
+{
+ MP_dRCFG;
+ MP_dDCFG;
+ modperl_wbucket_t *wb;
+
+ if (!rcfg->wbucket) {
+ rcfg->wbucket =
+ (modperl_wbucket_t *)apr_palloc(r->pool,
+ sizeof(*rcfg->wbucket));
+ }
+
+ wb = rcfg->wbucket;
+
+ /* setup buffer for output */
+ wb->pool = r->pool;
+ wb->filters = &r->output_filters;
+ wb->outcnt = 0;
+ wb->header_parse = MpDirPARSE_HEADERS(dcfg) && MpReqPARSE_HEADERS(rcfg)
+ ? 1 : 0;
+ wb->r = r;
+}
+
+apr_status_t modperl_response_finish(request_rec *r)
+{
+ MP_dRCFG;
+
+ /* flush output buffer */
+ return modperl_wbucket_flush(rcfg->wbucket, FALSE);
+}
+
+static int modperl_response_handler_run(request_rec *r)
+{
+ int retval;
+
+ modperl_response_init(r);
+
+ retval = modperl_callback_per_dir(MP_RESPONSE_HANDLER, r, MP_HOOK_RUN_FIRST);
+
+ if ((retval == DECLINED) && r->content_type) {
+ r->handler = r->content_type; /* let http_core or whatever try */
+ }
+
+ return retval;
+}
+
+int modperl_response_handler(request_rec *r)
+{
+ MP_dDCFG;
+ apr_status_t retval, rc;
+ MP_dINTERP;
+
+ if (!strEQ(r->handler, "modperl")) {
+ return DECLINED;
+ }
+
+ MP_INTERPa(r, r->connection, r->server);
+
+ /* default is -SetupEnv, add if PerlOption +SetupEnv */
+ if (MpDirSETUP_ENV(dcfg)) {
+ modperl_env_request_populate(aTHX_ r);
+ }
+
+ retval = modperl_response_handler_run(r);
+ rc = modperl_response_finish(r);
+ if (rc != APR_SUCCESS) {
+ retval = rc;
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ return retval;
+}
+
+int modperl_response_handler_cgi(request_rec *r)
+{
+ MP_dDCFG;
+ GV *h_stdin, *h_stdout;
+ apr_status_t retval, rc;
+ MP_dRCFG;
+ MP_dINTERP;
+
+ if (!strEQ(r->handler, "perl-script")) {
+ return DECLINED;
+ }
+
+ MP_INTERPa(r, r->connection, r->server);
+
+ modperl_perl_global_request_save(aTHX_ r);
+
+ /* default is +SetupEnv, skip if PerlOption -SetupEnv */
+ if (MpDirSETUP_ENV(dcfg) || !MpDirSeenSETUP_ENV(dcfg)) {
+ modperl_env_request_populate(aTHX_ r);
+ }
+
+ /* default is +GlobalRequest, skip if PerlOption -GlobalRequest */
+ if (MpDirGLOBAL_REQUEST(dcfg) || !MpDirSeenGLOBAL_REQUEST(dcfg)) {
+ modperl_global_request_set(r);
+ }
+
+ /* need to create a block around the IO setup so the temp vars
+ * will be automatically cleaned up when we are done with IO */
+ ENTER;SAVETMPS;
+ h_stdin = modperl_io_override_stdin(aTHX_ r);
+ h_stdout = modperl_io_override_stdout(aTHX_ r);
+
+ modperl_env_request_tie(aTHX_ r);
+
+ retval = modperl_response_handler_run(r);
+
+ modperl_env_request_untie(aTHX_ r);
+
+ modperl_perl_global_request_restore(aTHX_ r);
+
+ modperl_io_restore_stdin(aTHX_ h_stdin);
+ modperl_io_restore_stdout(aTHX_ h_stdout);
+ FREETMPS;LEAVE;
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ /* flush output buffer after interpreter is putback */
+ rc = modperl_response_finish(r);
+ if (rc != APR_SUCCESS) {
+ retval = rc;
+ }
+
+ switch (rcfg->status) {
+ case HTTP_MOVED_TEMPORARILY:
+ /* set by modperl_cgi_header_parse */
+ retval = HTTP_MOVED_TEMPORARILY;
+ break;
+ }
+
+ return retval;
+}
+
+/* This ugly hack pulls in any function listed in
+ * modperl_exports.c. Otherwise, the over-zealous
+ * linker would remove unused api functions
+ */
+const void *modperl_suck_in_ugly_hack(void);
+const void *modperl_suck_in_ugly_hack(void)
+{
+ extern const void *modperl_ugly_hack;
+ return modperl_ugly_hack;
+}
+
+module AP_MODULE_DECLARE_DATA perl_module = {
+ STANDARD20_MODULE_STUFF,
+ modperl_config_dir_create, /* dir config creater */
+ modperl_config_dir_merge, /* dir merger --- default is to override */
+ modperl_config_srv_create, /* server config */
+ modperl_config_srv_merge, /* merge server config */
+ modperl_cmds, /* table of config file commands */
+ modperl_register_hooks, /* register hooks */
+};
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/mod_perl.h b/2_0_13/src/modules/perl/mod_perl.h
new file mode 100644
index 0000000..e11e7a8
--- /dev/null
+++ b/2_0_13/src/modules/perl/mod_perl.h
@@ -0,0 +1,207 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOD_PERL_H
+#define MOD_PERL_H
+
+#include "modperl_apache_includes.h"
+#include "modperl_common_includes.h"
+#include "modperl_apache_compat.h"
+
+#ifdef WIN32
+#define MP_THREADED 1
+#else
+#define MP_THREADED (defined(USE_ITHREADS) && APR_HAS_THREADS)
+#endif
+
+extern module AP_MODULE_DECLARE_DATA perl_module;
+
+#include "modperl_error.h"
+#include "modperl_flags.h"
+#include "modperl_hooks.h"
+#include "modperl_perl_global.h"
+#include "modperl_perl_pp.h"
+#include "modperl_sys.h"
+#include "modperl_const.h"
+#include "modperl_constants.h"
+
+/* both perl and apr have largefile support enabled */
+#if defined(USE_LARGE_FILES) && APR_HAS_LARGE_FILES
+#define MP_LARGE_FILES_ENABLED
+#endif
+
+/* both perl and apr have largefile support disabled */
+#if (!defined(USE_LARGE_FILES)) && !APR_HAS_LARGE_FILES
+#define MP_LARGE_FILES_DISABLED
+#endif
+
+/* perl largefile support is enabled, apr support is disabled */
+#if defined(USE_LARGE_FILES) && !APR_HAS_LARGE_FILES
+#define MP_LARGE_FILES_PERL_ONLY
+#endif
+
+/* apr largefile support is enabled, perl support is disabled */
+#if (!defined(USE_LARGE_FILES)) && APR_HAS_LARGE_FILES
+#define MP_LARGE_FILES_APR_ONLY
+#endif
+
+/* conflict due to not have either both perl and apr
+ * support enabled or both disabled
+ */
+#if defined(MP_LARGE_FILES_APR_ONLY) || defined(MP_LARGE_FILES_PERL_ONLY)
+#define MP_LARGE_FILES_CONFLICT
+#endif
+
+#ifdef MP_USE_GTOP
+#include "modperl_gtop.h"
+#endif
+#include "modperl_time.h"
+#include "modperl_types.h"
+#include "modperl_util.h"
+#include "modperl_config.h"
+#include "modperl_cmd.h"
+#include "modperl_handler.h"
+#include "modperl_callback.h"
+#include "modperl_tipool.h"
+#include "modperl_interp.h"
+#include "modperl_log.h"
+#include "modperl_options.h"
+#include "modperl_directives.h"
+#include "modperl_io.h"
+#include "modperl_io_apache.h"
+#include "modperl_filter.h"
+#include "modperl_bucket.h"
+#include "modperl_pcw.h"
+#include "modperl_mgv.h"
+#include "modperl_global.h"
+#include "modperl_env.h"
+#include "modperl_cgi.h"
+#include "modperl_perl.h"
+#include "modperl_svptr_table.h"
+#include "modperl_module.h"
+#include "modperl_debug.h"
+
+int modperl_threads_started(void);
+int modperl_threaded_mpm(void);
+int modperl_post_post_config_phase(void);
+
+#define MP_CROAK_IF_THREADS_STARTED(what) \
+ if (modperl_threads_started()) { \
+ Perl_croak(aTHX_ "Can't run '%s' in the threaded " \
+ "environment after server startup", what); \
+ }
+
+#define MP_CROAK_IF_THREADED_MPM(what) \
+ if (modperl_threaded_mpm()) { \
+ Perl_croak(aTHX_ "Can't run '%s' in a threaded mpm", \
+ what); \
+ }
+
+#define MP_CROAK_IF_POST_POST_CONFIG_PHASE(what) \
+ if (modperl_post_post_config_phase()) { \
+ Perl_croak(aTHX_ "Can't run '%s' after server startup", \
+ what); \
+ }
+
+int modperl_init_vhost(server_rec *s, apr_pool_t *p,
+ server_rec *base_server);
+void modperl_init(server_rec *s, apr_pool_t *p);
+void modperl_init_globals(server_rec *s, apr_pool_t *pconf);
+int modperl_run(void);
+int modperl_is_running(void);
+int modperl_hook_init(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s);
+int modperl_hook_pre_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp);
+void modperl_register_hooks(apr_pool_t *p);
+apr_pool_t *modperl_server_pool(void);
+apr_pool_t *modperl_server_user_pool(void);
+PerlInterpreter *modperl_startup(server_rec *s, apr_pool_t *p);
+int modperl_perl_destruct_level(void);
+void xs_init(pTHX);
+
+void modperl_response_init(request_rec *r);
+apr_status_t modperl_response_finish(request_rec *r);
+int modperl_response_handler(request_rec *r);
+int modperl_response_handler_cgi(request_rec *r);
+
+#define MgTypeExt(mg) (mg->mg_type == '~')
+
+typedef void MP_FUNC_NONSTD_T(modperl_var_modify_t) (apr_table_t *,
+ apr_table_t *,
+ const char *,
+ const char *);
+
+/* we need to hook a few internal things before APR_HOOK_REALLY_FIRST */
+#define MODPERL_HOOK_REALLY_REALLY_FIRST (-20)
+
+#ifdef USE_ITHREADS
+APR_DECLARE_OPTIONAL_FN(apr_status_t,modperl_interp_unselect,(void *));
+APR_DECLARE_OPTIONAL_FN(modperl_interp_t *,modperl_thx_interp_get,(PerlInterpreter *));
+#endif
+
+/*
+ * perl context overriding and restoration is required when
+ * PerlOptions +Parent/+Clone is used in vhosts, and perl is used to
+ * at the server startup. So that <Perl> sections, PerlLoadModule,
+ * PerlModule and PerlRequire are all run using the right perl context
+ * and restore to the original context when they are done.
+ *
+ * As of perl-5.8.3 it's unfortunate that it uses PERL_GET_CONTEXT and
+ * doesn't rely on the passed pTHX internally. When and if perl is
+ * fixed to always use pTHX if available, this context switching mess
+ * can be removed.
+ */
+#ifdef USE_ITHREADS
+
+#define MP_PERL_CONTEXT_DECLARE \
+ PerlInterpreter *orig_perl = NULL; \
+ pTHX;
+
+#define MP_PERL_CONTEXT_STORE \
+ orig_perl = PERL_GET_CONTEXT;
+
+#define MP_PERL_CONTEXT_OVERRIDE(new_perl) \
+ aTHX = new_perl; \
+ PERL_SET_CONTEXT(aTHX);
+
+#define MP_PERL_CONTEXT_STORE_OVERRIDE(new_perl) \
+ MP_PERL_CONTEXT_STORE; \
+ MP_PERL_CONTEXT_OVERRIDE(new_perl)
+
+#define MP_PERL_CONTEXT_RESTORE \
+ if (orig_perl) { \
+ PERL_SET_CONTEXT(orig_perl); \
+ }
+
+#else /* #ifdef USE_ITHREADS */
+
+#define MP_PERL_CONTEXT_DECLARE
+#define MP_PERL_CONTEXT_STORE
+#define MP_PERL_CONTEXT_OVERRIDE(new_perl)
+#define MP_PERL_CONTEXT_STORE_OVERRIDE(new_perl)
+#define MP_PERL_CONTEXT_RESTORE
+
+#endif /* end of #ifdef USE_ITHREADS */
+
+#endif /* MOD_PERL_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_apache_compat.c b/2_0_13/src/modules/perl/modperl_apache_compat.c
new file mode 100644
index 0000000..1c1700b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_apache_compat.c
@@ -0,0 +1,79 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define AP_DECLARE_EXPORT
+#include "mod_perl.h"
+
+/* back compat adjustements for older Apache versions
+ * BACK_COMPAT_MARKER: make back compat issues easy to find :)
+ */
+
+/* use the following format:
+ * #if ! AP_MODULE_MAGIC_AT_LEAST(20020903,4)
+ * [compat code]
+ * #endif
+ * and don't forget to insert comments explaining exactly
+ * which httpd release allows us to remove the compat code
+ */
+
+/* pre-APACHE_2.2.4 */
+#if ! AP_MODULE_MAGIC_AT_LEAST(20051115,4)
+
+#define modperl_warn_fallback_http_function(ver, fallback) \
+ { \
+ dTHX; \
+ Perl_warn(aTHX_ "%s() not available until httpd/%s " \
+ "falling back to %s()", \
+ MP_FUNC, ver, fallback); \
+ }
+
+/* added in APACHE_2.2.4 */
+AP_DECLARE(const char *) ap_get_server_description(void) {
+ modperl_warn_fallback_http_function("2.2.4", "ap_get_server_version");
+ return ap_get_server_version();
+}
+
+AP_DECLARE(const char *) ap_get_server_banner(void) {
+ modperl_warn_fallback_http_function("2.2.4", "ap_get_server_version");
+ return ap_get_server_version();
+}
+
+#endif /* pre-APACHE_2.2.4 */
+
+/* since-APACHE-2.3.0 */
+#if AP_MODULE_MAGIC_AT_LEAST(20060905,0)
+#define modperl_warn_deprecated_http_function(ver, fallback) \
+ { \
+ dTHX; \
+ Perl_warn(aTHX_ "%s() is deprecated since httpd/%s " \
+ "try using %s() instead", \
+ MP_FUNC, ver, fallback); \
+ }
+
+AP_DECLARE(const char *) ap_get_server_version(void) {
+ modperl_warn_deprecated_http_function("2.3.0",
+ "ap_get_server_(description|banner)");
+ return ap_get_server_banner();
+}
+
+#endif /* since-APACHE-2.3.0 */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_apache_compat.h b/2_0_13/src/modules/perl/modperl_apache_compat.h
new file mode 100644
index 0000000..0d7058b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_apache_compat.h
@@ -0,0 +1,111 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_APACHE_COMPAT_H
+#define MODPERL_APACHE_COMPAT_H
+
+/* back compat adjustements for older Apache versions */
+
+#if !APR_HAS_THREADS
+typedef unsigned long apr_os_thread_t;
+typedef void * apr_thread_mutex_t;
+typedef void * apr_thread_rwlock_t;
+#endif
+
+/* back compat adjustements for older Apache versions
+ * BACK_COMPAT_MARKER: make back compat issues easy to find :)
+ */
+
+/* use the following format:
+ * #if ! AP_MODULE_MAGIC_AT_LEAST(20020903,4)
+ * [compat code]
+ * #endif
+ * and don't forget to insert comments explaining exactly
+ * which httpd release allows us to remove the compat code
+ */
+
+/* pre-APACHE_2.2.4 */
+#if ! AP_MODULE_MAGIC_AT_LEAST(20051115,4)
+
+/* added in APACHE_2.2.4 */
+AP_DECLARE(const char *) ap_get_server_description(void);
+AP_DECLARE(const char *) ap_get_server_banner(void);
+
+#endif /* pre-APACHE_2.2.4 */
+
+/* since-APACHE-2.3.0 */
+#if AP_MODULE_MAGIC_AT_LEAST(20060905,0)
+
+/* removed in APACHE-2.3.0 */
+AP_DECLARE(const char *) ap_get_server_version(void);
+
+#endif /* since-APACHE-2.3.0 */
+
+/* ap_http_scheme is called ap_http_method in httpd 2.0 */
+#ifndef ap_http_scheme
+#define ap_http_scheme(r) ap_http_method(r)
+#endif
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || AP_SERVER_MINORVERSION_NUMBER>=2
+#define MP_HTTPD_HAS_OVERRIDE_OPTS
+#endif
+
+#define MP_HTTPD_OVERRIDE_HTACCESS (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)
+
+#define MP_HTTPD_OVERRIDE_OPTS_UNSET (-1)
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+
+/* 2.4 API */
+#define MP_HTTPD_OVERRIDE_OPTS_DEFAULT (OPT_UNSET | \
+ OPT_ALL | \
+ OPT_SYM_OWNER | \
+ OPT_MULTI)
+#define mp_add_loaded_module(modp, pool, name) \
+ ap_add_loaded_module((modp), (pool), (name))
+
+#define mp_loglevel(s) ((s)->log.level)
+#define mp_module_index_ perl_module.module_index,
+
+#else
+/* 2.2 API */
+#define MP_HTTPD_OVERRIDE_OPTS_DEFAULT (OPT_UNSET | \
+ OPT_ALL | \
+ OPT_INCNOEXEC | \
+ OPT_SYM_OWNER | \
+ OPT_MULTI)
+#define mp_add_loaded_module(modp, pool, name) \
+ ap_add_loaded_module((modp), (pool))
+
+#define mp_loglevel(s) ((s)->loglevel)
+#define mp_module_index_
+
+#define ap_unixd_config unixd_config
+
+#endif /* 2.4 vs. 2.2 API */
+
+#ifndef PROXYREQ_RESPONSE
+#define PROXYREQ_RESPONSE (3)
+#endif
+
+#endif /* MODPERL_APACHE_COMPAT_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_apache_includes.h b/2_0_13/src/modules/perl/modperl_apache_includes.h
new file mode 100644
index 0000000..a06cc2b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_apache_includes.h
@@ -0,0 +1,59 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_APACHE_INCLUDES_H
+#define MODPERL_APACHE_INCLUDES_H
+
+/* header files for Apache */
+
+#ifndef CORE_PRIVATE
+#define CORE_PRIVATE
+#endif
+
+#include "ap_mmn.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_main.h"
+#include "http_request.h"
+#include "http_connection.h"
+#include "http_core.h"
+#include "http_vhost.h"
+#include "ap_mpm.h"
+
+#include "util_filter.h"
+
+#include "util_script.h"
+
+#if !defined(MP_IN_XS) && AP_MODULE_MAGIC_AT_LEAST(20100606, 0)
+APLOG_USE_MODULE(perl);
+#endif
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+#include "ap_provider.h"
+#include "mod_auth.h"
+#endif
+
+#endif /* MODPERL_APACHE_INCLUDES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_apr_compat.h b/2_0_13/src/modules/perl/modperl_apr_compat.h
new file mode 100644
index 0000000..e9d5da4
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_apr_compat.h
@@ -0,0 +1,162 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_APR_COMPAT_H
+#define MODPERL_APR_COMPAT_H
+
+/* back compat adjustements for older libapr versions */
+
+/* BACK_COMPAT_MARKER: make back compat issues easy to find :) */
+
+/* use the following format:
+ * #if ! AP_MODULE_MAGIC_AT_LEAST(20020903,4)
+ * [compat code]
+ * #endif
+ * and don't forget to insert comments explaining exactly
+ * which httpd release allows us to remove the compat code
+ */
+
+/* apr_filetype_e entries rename */
+
+#ifndef APR_FILETYPE_NOFILE
+#define APR_FILETYPE_NOFILE APR_NOFILE
+#endif
+#ifndef APR_FILETYPE_REG
+#define APR_FILETYPE_REG APR_REG
+#endif
+#ifndef APR_FILETYPE_DIR
+#define APR_FILETYPE_DIR APR_DIR
+#endif
+#ifndef APR_FILETYPE_CHR
+#define APR_FILETYPE_CHR APR_CHR
+#endif
+#ifndef APR_FILETYPE_BLK
+#define APR_FILETYPE_BLK APR_BLK
+#endif
+#ifndef APR_FILETYPE_PIPE
+#define APR_FILETYPE_PIPE APR_PIPE
+#endif
+#ifndef APR_FILETYPE_LNK
+#define APR_FILETYPE_LNK APR_LNK
+#endif
+#ifndef APR_FILETYPE_SOCK
+#define APR_FILETYPE_SOCK APR_SOCK
+#endif
+#ifndef APR_FILETYPE_UNKFILE
+#define APR_FILETYPE_UNKFILE APR_UNKFILE
+#endif
+
+
+/* apr file permissions group rename (has no enum) */
+
+#if defined(APR_USETID) && !defined(APR_FPROT_USETID)
+#define APR_FPROT_USETID APR_USETID
+#endif
+#ifndef APR_FPROT_UREAD
+#define APR_FPROT_UREAD APR_UREAD
+#endif
+#ifndef APR_FPROT_UWRITE
+#define APR_FPROT_UWRITE APR_UWRITE
+#endif
+#ifndef APR_FPROT_UEXECUTE
+#define APR_FPROT_UEXECUTE APR_UEXECUTE
+#endif
+#if defined(APR_GSETID) && !defined(APR_FPROT_GSETID)
+#define APR_FPROT_GSETID APR_GSETID
+#endif
+#ifndef APR_FPROT_GREAD
+#define APR_FPROT_GREAD APR_GREAD
+#endif
+#ifndef APR_FPROT_GWRITE
+#define APR_FPROT_GWRITE APR_GWRITE
+#endif
+#ifndef APR_FPROT_GEXECUTE
+#define APR_FPROT_GEXECUTE APR_GEXECUTE
+#endif
+#if defined(APR_WSTICKY) && !defined(APR_FPROT_WSTICKY)
+#define APR_FPROT_WSTICKY APR_WSTICKY
+#endif
+#ifndef APR_FPROT_WREAD
+#define APR_FPROT_WREAD APR_WREAD
+#endif
+#ifndef APR_FPROT_WWRITE
+#define APR_FPROT_WWRITE APR_WWRITE
+#endif
+#ifndef APR_FPROT_WEXECUTE
+#define APR_FPROT_WEXECUTE APR_WEXECUTE
+#endif
+#ifndef APR_FPROT_OS_DEFAULT
+#define APR_FPROT_OS_DEFAULT APR_OS_DEFAULT
+#endif
+/* APR_FPROT_FILE_SOURCE_PERMS seems to have only an internal apr
+ * use */
+
+/* apr_file_open flag group rename (has no enum) */
+
+#ifndef APR_FOPEN_READ
+#define APR_FOPEN_READ APR_READ
+#endif
+#ifndef APR_FOPEN_WRITE
+#define APR_FOPEN_WRITE APR_WRITE
+#endif
+#ifndef APR_FOPEN_CREATE
+#define APR_FOPEN_CREATE APR_CREATE
+#endif
+#ifndef APR_FOPEN_APPEND
+#define APR_FOPEN_APPEND APR_APPEND
+#endif
+#ifndef APR_FOPEN_TRUNCATE
+#define APR_FOPEN_TRUNCATE APR_TRUNCATE
+#endif
+#ifndef APR_FOPEN_BINARY
+#define APR_FOPEN_BINARY APR_BINARY
+#endif
+#ifndef APR_FOPEN_EXCL
+#define APR_FOPEN_EXCL APR_EXCL
+#endif
+#ifndef APR_FOPEN_BUFFERED
+#define APR_FOPEN_BUFFERED APR_BUFFERED
+#endif
+#ifndef APR_FOPEN_DELONCLOSE
+#define APR_FOPEN_DELONCLOSE APR_DELONCLOSE
+#endif
+#ifndef APR_FOPEN_XTHREAD
+#define APR_FOPEN_XTHREAD APR_XTHREAD
+#endif
+#ifndef APR_FOPEN_SHARELOCK
+#define APR_FOPEN_SHARELOCK APR_SHARELOCK
+#endif
+#ifndef APR_FOPEN_NOCLEANUP
+#define APR_FOPEN_NOCLEANUP APR_FILE_NOCLEANUP
+#endif
+#ifndef APR_FOPEN_SENDFILE_ENABLED
+#define APR_FOPEN_SENDFILE_ENABLED APR_SENDFILE_ENABLED
+#endif
+#ifndef APR_FOPEN_LARGEFILE
+/* added in 2.0.50 */
+#ifdef APR_LARGEFILE
+#define APR_FOPEN_LARGEFILE APR_LARGEFILE
+#endif
+#endif
+
+#endif /* MODPERL_APR_COMPAT_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_apr_includes.h b/2_0_13/src/modules/perl/modperl_apr_includes.h
new file mode 100644
index 0000000..ec6e3d6
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_apr_includes.h
@@ -0,0 +1,51 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_APR_INCLUDES_H
+#define MODPERL_APR_INCLUDES_H
+
+/* header files for APR */
+
+#ifndef CORE_PRIVATE
+#define CORE_PRIVATE
+#endif
+
+#include "apr_version.h"
+#include "apr_poll.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "apr_uri.h"
+#include "apr_date.h"
+#include "apr_buckets.h"
+#include "apr_time.h"
+#include "apr_network_io.h"
+#include "apr_general.h"
+#include "apr_uuid.h"
+#include "apr_env.h"
+#include "apu_version.h"
+#if APU_MAJOR_VERSION > 1 \
+ || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION > 3)
+#include "apu_errno.h"
+#endif
+
+#endif /* MODPERL_APR_INCLUDES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_bucket.c b/2_0_13/src/modules/perl/modperl_bucket.c
new file mode 100644
index 0000000..f5f2c98
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_bucket.c
@@ -0,0 +1,165 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/*
+ * modperl_bucket_sv code derived from mod_snake's ModSnakePyBucket
+ * by Jon Travis
+ */
+
+typedef struct {
+ apr_bucket_refcount refcount;
+ SV *sv;
+ PerlInterpreter *perl;
+} modperl_bucket_sv_t;
+
+static apr_status_t
+modperl_bucket_sv_read(apr_bucket *bucket, const char **str,
+ apr_size_t *len, apr_read_type_e block)
+{
+ modperl_bucket_sv_t *svbucket = bucket->data;
+ dTHXa(svbucket->perl);
+ STRLEN svlen;
+ char *pv = SvPV(svbucket->sv, svlen);
+
+ *str = pv + bucket->start;
+ *len = bucket->length;
+
+ if (svlen < bucket->start + bucket->length) {
+ /* XXX log error? */
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+}
+
+static void modperl_bucket_sv_destroy(void *data)
+{
+ modperl_bucket_sv_t *svbucket = data;
+ dTHXa(svbucket->perl);
+
+ if (!apr_bucket_shared_destroy(svbucket)) {
+ MP_TRACE_f(MP_FUNC, "bucket refcnt=%d",
+ ((apr_bucket_refcount *)svbucket)->refcount);
+ return;
+ }
+
+ MP_TRACE_f(MP_FUNC, "sv=0x%lx, refcnt=%d",
+ (unsigned long)svbucket->sv, SvREFCNT(svbucket->sv));
+
+ SvREFCNT_dec(svbucket->sv);
+
+ apr_bucket_free(svbucket);
+}
+
+static
+apr_status_t modperl_bucket_sv_setaside(apr_bucket *bucket, apr_pool_t *pool)
+{
+ modperl_bucket_sv_t *svbucket = bucket->data;
+ dTHXa(svbucket->perl);
+ STRLEN svlen;
+ char *pv = SvPV(svbucket->sv, svlen);
+
+ if (svlen < bucket->start + bucket->length) {
+ /* XXX log error? */
+ return APR_EGENERAL;
+ }
+
+ pv = apr_pstrmemdup(pool, pv + bucket->start, bucket->length);
+ if (pv == NULL) {
+ return APR_ENOMEM;
+ }
+
+ /* changes bucket guts by reference */
+ if (apr_bucket_pool_make(bucket, pv, bucket->length, pool) == NULL) {
+ return APR_ENOMEM;
+ }
+
+ modperl_bucket_sv_destroy(svbucket);
+ return APR_SUCCESS;
+}
+
+static const apr_bucket_type_t modperl_bucket_sv_type = {
+ "mod_perl SV bucket", 4,
+#if MODULE_MAGIC_NUMBER >= 20020602
+ APR_BUCKET_DATA,
+#endif
+ modperl_bucket_sv_destroy,
+ modperl_bucket_sv_read,
+ modperl_bucket_sv_setaside,
+ apr_bucket_shared_split,
+ apr_bucket_shared_copy,
+};
+
+static apr_bucket *modperl_bucket_sv_make(pTHX_
+ apr_bucket *bucket,
+ SV *sv,
+ apr_off_t offset,
+ apr_size_t len)
+{
+ modperl_bucket_sv_t *svbucket;
+
+ svbucket = apr_bucket_alloc(sizeof(*svbucket), bucket->list);
+
+ bucket = apr_bucket_shared_make(bucket, svbucket, offset, len);
+ if (!bucket) {
+ apr_bucket_free(svbucket);
+ return NULL;
+ }
+
+#ifdef USE_ITHREADS
+ svbucket->perl = aTHX;
+#endif
+
+ /* PADTMP SVs belong to perl and can't be stored away, since perl
+ * is going to reuse them, so we have no choice but to copy the
+ * data away, before storing sv */
+ if (SvPADTMP(sv)) {
+ STRLEN len;
+ char *pv = SvPV(sv, len);
+ svbucket->sv = newSVpvn(pv, len);
+ }
+ else {
+ svbucket->sv = sv;
+ (void)SvREFCNT_inc(svbucket->sv);
+ }
+
+ MP_TRACE_f(MP_FUNC, "sv=0x%lx, refcnt=%d",
+ (unsigned long)svbucket->sv, SvREFCNT(svbucket->sv));
+
+ bucket->type = &modperl_bucket_sv_type;
+ return bucket;
+}
+
+apr_bucket *modperl_bucket_sv_create(pTHX_ apr_bucket_alloc_t *list, SV *sv,
+ apr_off_t offset, apr_size_t len)
+{
+ apr_bucket *bucket;
+
+ bucket = apr_bucket_alloc(sizeof(*bucket), list);
+ APR_BUCKET_INIT(bucket);
+ bucket->list = list;
+ bucket->free = apr_bucket_free;
+ return modperl_bucket_sv_make(aTHX_ bucket, sv, offset, len);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_bucket.h b/2_0_13/src/modules/perl/modperl_bucket.h
new file mode 100644
index 0000000..f01506a
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_bucket.h
@@ -0,0 +1,30 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_BUCKET_H
+#define MODPERL_BUCKET_H
+
+apr_bucket *modperl_bucket_sv_create(pTHX_ apr_bucket_alloc_t *list, SV *sv,
+ apr_off_t offset, apr_size_t len);
+
+#endif /* MODPERL_BUCKET_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_callback.c b/2_0_13/src/modules/perl/modperl_callback.c
new file mode 100644
index 0000000..04f4317
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_callback.c
@@ -0,0 +1,397 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p,
+ request_rec *r, server_rec *s, AV *args)
+{
+ CV *cv = (CV *)NULL;
+ I32 flags = G_EVAL|G_SCALAR;
+ dSP;
+ int count, status = OK;
+
+ /* handler callbacks shouldn't affect each other's taintedness
+ * state, so start every callback with a clear tainted status
+ * before and after the callback one of the main problems we are
+ * trying to solve is that when modperl_croak called (which calls
+ * perl's croak((char *)NULL) to throw an error object) it leaves
+ * the interpreter in the tainted state which later affects other
+ * callbacks that call eval, etc., which triggers perl crash with:
+ * Insecure dependency in eval while running setgid. Callback
+ * called exit.
+ */
+ TAINT_NOT;
+
+ if ((status = modperl_handler_resolve(aTHX_ &handler, p, s)) != OK) {
+ TAINT_NOT;
+ return status;
+ }
+
+ ENTER;SAVETMPS;
+ PUSHMARK(SP);
+
+ if (MpHandlerMETHOD(handler)) {
+ GV *gv;
+ if (!handler->mgv_obj) {
+ Perl_croak(aTHX_ "panic: %s method handler object is NULL!",
+ modperl_handler_name(handler));
+ }
+ gv = modperl_mgv_lookup(aTHX_ handler->mgv_obj);
+ XPUSHs(modperl_mgv_sv(gv));
+ }
+
+ if (args) {
+ I32 items = AvFILLp(args) + 1;
+
+ EXTEND(SP, items);
+ Copy(AvARRAY(args), SP + 1, items, SV*);
+ SP += items;
+ }
+
+ PUTBACK;
+
+ if (MpHandlerANON(handler)) {
+#ifdef USE_ITHREADS
+ cv = modperl_handler_anon_get(aTHX_ handler->mgv_obj);
+#else
+ cv = handler->cv;
+#endif
+ }
+ else {
+ GV *gv = modperl_mgv_lookup_autoload(aTHX_ handler->mgv_cv, s, p);
+ if (gv) {
+ cv = modperl_mgv_cv(gv);
+ }
+ else {
+ const char *name;
+ modperl_mgv_t *symbol = handler->mgv_cv;
+
+ /* XXX: need to validate *symbol */
+ if (symbol && symbol->name) {
+ name = modperl_mgv_as_string(aTHX_ symbol, p, 0);
+ }
+ else {
+ name = handler->name;
+ }
+
+ MP_TRACE_h(MP_FUNC, "[%s] lookup of %s failed",
+ modperl_server_desc(s, p), name);
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "lookup of '%s' failed", name);
+ status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ if (status == OK) {
+ count = call_sv((SV*)cv, flags);
+
+ SPAGAIN;
+
+ if (count != 1) {
+ /* XXX can this really happen with G_EVAL|G_SCALAR? */
+ status = OK;
+ }
+ else {
+ SV *status_sv = POPs;
+
+ if (status_sv == &PL_sv_undef) {
+ /* ModPerl::Util::exit() and Perl_croak internally
+ * arrange to return PL_sv_undef with G_EVAL|G_SCALAR */
+ status = OK;
+ }
+ else {
+ status = SvIVx(status_sv);
+ }
+ }
+
+ PUTBACK;
+ }
+
+ FREETMPS;LEAVE;
+
+ if (SvTRUE(ERRSV)) {
+ MP_TRACE_h(MP_FUNC, "$@ = %s", SvPV_nolen(ERRSV));
+ status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (status == HTTP_INTERNAL_SERVER_ERROR) {
+ if (r && r->notes) {
+ apr_table_merge(r->notes, "error-notes", SvPV_nolen(ERRSV));
+ }
+ }
+
+ TAINT_NOT;
+
+ return status;
+}
+
+int modperl_callback_run_handlers(int idx, int type,
+ request_rec *r, conn_rec *c,
+ server_rec *s,
+ apr_pool_t *pconf,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ modperl_hook_run_mode_e run_mode)
+{
+ MP_dINTERP;
+ MP_dSCFG(s);
+ MP_dDCFG;
+ MP_dRCFG;
+ modperl_handler_t **handlers;
+ apr_pool_t *p = NULL;
+ MpAV *av, **avp;
+ int i, status = OK;
+ const char *desc = NULL;
+ AV *av_args = (AV *)NULL;
+
+ if (!MpSrvENABLE(scfg)) {
+ MP_TRACE_h(MP_FUNC, "PerlOff for server %s:%u",
+ s->server_hostname, s->port);
+ return DECLINED;
+ }
+
+ if (r || c) {
+ p = c ? c->pool : r->pool;
+ }
+ else {
+ p = pconf;
+ }
+
+ avp = modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p,
+ type, idx, FALSE, &desc);
+
+ if (!(avp && (av = *avp))) {
+ MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)",
+ desc, r ? r->uri : "");
+ return DECLINED;
+ }
+
+ MP_INTERPa(r, c, s);
+
+ switch (type) {
+ case MP_HANDLER_TYPE_PER_SRV:
+ modperl_handler_make_args(aTHX_ &av_args,
+ "Apache2::RequestRec", r, NULL);
+
+ /* per-server PerlSetEnv and PerlPassEnv - only once per-request */
+ if (! MpReqPERL_SET_ENV_SRV(rcfg)) {
+ modperl_env_configure_request_srv(aTHX_ r);
+ }
+
+ break;
+ case MP_HANDLER_TYPE_PER_DIR:
+ modperl_handler_make_args(aTHX_ &av_args,
+ "Apache2::RequestRec", r, NULL);
+
+ /* per-server PerlSetEnv and PerlPassEnv - only once per-request */
+ if (! MpReqPERL_SET_ENV_SRV(rcfg)) {
+ modperl_env_configure_request_srv(aTHX_ r);
+ }
+
+ /* per-directory PerlSetEnv - only once per-request */
+ if (! MpReqPERL_SET_ENV_DIR(rcfg)) {
+ modperl_env_configure_request_dir(aTHX_ r);
+ }
+
+ break;
+ case MP_HANDLER_TYPE_PRE_CONNECTION:
+ case MP_HANDLER_TYPE_CONNECTION:
+ modperl_handler_make_args(aTHX_ &av_args,
+ "Apache2::Connection", c, NULL);
+ break;
+ case MP_HANDLER_TYPE_FILES:
+ modperl_handler_make_args(aTHX_ &av_args,
+ "APR::Pool", pconf,
+ "APR::Pool", plog,
+ "APR::Pool", ptemp,
+ "Apache2::ServerRec", s, NULL);
+ break;
+ case MP_HANDLER_TYPE_PROCESS:
+ modperl_handler_make_args(aTHX_ &av_args,
+ "APR::Pool", pconf,
+ "Apache2::ServerRec", s, NULL);
+ break;
+ };
+
+ modperl_callback_current_callback_set(desc);
+
+ MP_TRACE_h(MP_FUNC, "running %d %s handlers", av->nelts, desc);
+ handlers = (modperl_handler_t **)av->elts;
+
+ for (i=0; i<av->nelts; i++) {
+ status = modperl_callback(aTHX_ handlers[i], p, r, s, av_args);
+
+ MP_TRACE_h(MP_FUNC, "callback '%s' returned %d",
+ modperl_handler_name(handlers[i]), status);
+
+ /* follow Apache's lead and let OK terminate the phase for
+ * MP_HOOK_RUN_FIRST handlers. MP_HOOK_RUN_ALL handlers keep
+ * going on OK. MP_HOOK_VOID handlers ignore all errors.
+ */
+
+ if (run_mode == MP_HOOK_RUN_ALL) {
+ /* special case */
+ if (type == MP_HANDLER_TYPE_FILES && status != OK) {
+ /* open_logs and post_config require OK return code or
+ * the server aborts, so we need to log an error in
+ * case the handler didn't fail but returned something
+ * different from OK */
+ if (SvTRUE(ERRSV)) {
+ status = modperl_errsv(aTHX_ status, r, s);
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Callback '%s' returned %d, whereas "
+ "Apache2::Const::OK (%d) is the only valid "
+ "return value for %s handlers",
+ modperl_handler_name(handlers[i]),
+ status, OK, desc);
+ }
+ break;
+ }
+ /* the normal case:
+ * OK and DECLINED continue
+ * errors end the phase
+ */
+ else if ((status != OK) && (status != DECLINED)) {
+
+ status = modperl_errsv(aTHX_ status, r, s);
+#ifdef MP_TRACE
+ if (i+1 != av->nelts) {
+ MP_TRACE_h(MP_FUNC, "error status %d leaves %d "
+ "uncalled %s handlers",
+ status, av->nelts-i-1, desc);
+ }
+#endif
+ break;
+ }
+ }
+ else if (run_mode == MP_HOOK_RUN_FIRST) {
+ /* the exceptional case:
+ * OK and errors end the phase
+ * DECLINED continues
+ */
+
+ if (status == OK) {
+#ifdef MP_TRACE
+ if (i+1 != av->nelts) {
+ MP_TRACE_h(MP_FUNC, "OK ends the %s stack, "
+ "leaving %d uncalled %s handlers",
+ desc, av->nelts-i-1, desc);
+ }
+#endif
+ break;
+ }
+ if (status != DECLINED) {
+ status = modperl_errsv(aTHX_ status, r, s);
+#ifdef MP_TRACE
+ if (i+1 != av->nelts) {
+ MP_TRACE_h(MP_FUNC, "error status %d leaves %d "
+ "uncalled %s handlers",
+ status, av->nelts-i-1, desc);
+ }
+#endif
+ break;
+ }
+ }
+ else {
+ /* the rare case.
+ * MP_HOOK_VOID handlers completely ignore the return status
+ * Apache should handle whatever mod_perl returns,
+ * so there is no need to mess with the status
+ */
+ }
+
+ /* it's possible that during the last callback a new handler
+ * was pushed onto the same phase it's running from. av needs
+ * to be updated.
+ *
+ * XXX: would be nice to somehow optimize that
+ */
+ avp = modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p,
+ type, idx, FALSE, NULL);
+ if (avp && (av = *avp)) {
+ handlers = (modperl_handler_t **)av->elts;
+ }
+ }
+
+ SvREFCNT_dec((SV*)av_args);
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ return status;
+}
+
+int modperl_callback_per_dir(int idx, request_rec *r,
+ modperl_hook_run_mode_e run_mode)
+{
+ return modperl_callback_run_handlers(idx, MP_HANDLER_TYPE_PER_DIR,
+ r, NULL, r->server,
+ NULL, NULL, NULL, run_mode);
+}
+
+int modperl_callback_per_srv(int idx, request_rec *r,
+ modperl_hook_run_mode_e run_mode)
+{
+ return modperl_callback_run_handlers(idx,
+ MP_HANDLER_TYPE_PER_SRV,
+ r, NULL, r->server,
+ NULL, NULL, NULL, run_mode);
+}
+
+int modperl_callback_connection(int idx, conn_rec *c,
+ modperl_hook_run_mode_e run_mode)
+{
+ return modperl_callback_run_handlers(idx,
+ MP_HANDLER_TYPE_CONNECTION,
+ NULL, c, c->base_server,
+ NULL, NULL, NULL, run_mode);
+}
+
+int modperl_callback_pre_connection(int idx, conn_rec *c, void *csd,
+ modperl_hook_run_mode_e run_mode)
+{
+ return modperl_callback_run_handlers(idx,
+ MP_HANDLER_TYPE_PRE_CONNECTION,
+ NULL, c, c->base_server,
+ NULL, NULL, NULL, run_mode);
+}
+
+void modperl_callback_process(int idx, apr_pool_t *p, server_rec *s,
+ modperl_hook_run_mode_e run_mode)
+{
+ modperl_callback_run_handlers(idx, MP_HANDLER_TYPE_PROCESS,
+ NULL, NULL, s,
+ p, NULL, NULL, run_mode);
+}
+
+int modperl_callback_files(int idx,
+ apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s,
+ modperl_hook_run_mode_e run_mode)
+{
+ return modperl_callback_run_handlers(idx, MP_HANDLER_TYPE_FILES,
+ NULL, NULL, s,
+ pconf, plog, ptemp, run_mode);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_callback.h b/2_0_13/src/modules/perl/modperl_callback.h
new file mode 100644
index 0000000..8441b2d
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_callback.h
@@ -0,0 +1,75 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_CALLBACK_H
+#define MODPERL_CALLBACK_H
+
+/* alias some hook names to match Perl*Handler names */
+#define ap_hook_trans ap_hook_translate_name
+#define ap_hook_access ap_hook_access_checker
+#define ap_hook_authen ap_hook_check_user_id
+#define ap_hook_authz ap_hook_auth_checker
+#define ap_hook_type ap_hook_type_checker
+#define ap_hook_fixup ap_hook_fixups
+#define ap_hook_log ap_hook_log_transaction
+
+#define modperl_callback_current_callback_sv \
+ get_sv("Apache2::__CurrentCallback", TRUE)
+
+#define modperl_callback_current_callback_set(desc) \
+ sv_setpv(modperl_callback_current_callback_sv, desc)
+
+#define modperl_callback_current_callback_get() \
+ SvPVX(modperl_callback_current_callback_sv)
+
+int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p,
+ request_rec *r, server_rec *s, AV *args);
+
+int modperl_callback_run_handlers(int idx, int type,
+ request_rec *r, conn_rec *c, server_rec *s,
+ apr_pool_t *pconf,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ modperl_hook_run_mode_e run_mode);
+
+int modperl_callback_per_dir(int idx, request_rec *r,
+ modperl_hook_run_mode_e run_mode);
+
+int modperl_callback_per_srv(int idx, request_rec *r,
+ modperl_hook_run_mode_e run_mode);
+
+int modperl_callback_connection(int idx, conn_rec *c,
+ modperl_hook_run_mode_e run_mode);
+
+int modperl_callback_pre_connection(int idx, conn_rec *c, void *csd,
+ modperl_hook_run_mode_e run_mode);
+
+void modperl_callback_process(int idx, apr_pool_t *p, server_rec *s,
+ modperl_hook_run_mode_e run_mode);
+
+int modperl_callback_files(int idx,
+ apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s,
+ modperl_hook_run_mode_e run_mode);
+
+#endif /* MODPERL_CALLBACK_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_cgi.c b/2_0_13/src/modules/perl/modperl_cgi.c
new file mode 100644
index 0000000..66743e6
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_cgi.c
@@ -0,0 +1,110 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+MP_INLINE int modperl_cgi_header_parse(request_rec *r, char *buffer,
+ apr_size_t *len, const char **body)
+{
+ int status;
+ int termarg;
+ const char *location;
+ const char *tmp;
+ apr_size_t tlen, newln;
+
+ if (!buffer) {
+ return DECLINED;
+ }
+
+ /* ap_scan_script_header_err_strs won't handle correctly binary
+ * data following the headers, e.g. when the terminating /\n\r?\n/
+ * is followed by \0\0 which is a part of the response
+ * body. Therefore we need to separate the headers from the body
+ * and not rely on ap_scan_script_header_err_strs to do that for
+ * us.
+ */
+ tmp = buffer;
+ newln = 0;
+ tlen = *len;
+ while (tlen--) {
+ /* that strange mix of CR and \n (and not LF) copied from
+ * util_script.c:ap_scan_script_header_err_core
+ */
+ if (*tmp != CR && *tmp != '\n') {
+ newln = 0;
+ }
+ if (*tmp == '\n') {
+ newln++;
+ }
+ tmp++;
+ if (newln == 2) {
+ break;
+ }
+ }
+
+ if (tmp - buffer >= *len) {
+ *body = NULL; /* no body along with headers */
+ *len = 0;
+ }
+ else {
+ *body = tmp;
+ *len = *len - (tmp - buffer);
+ }
+
+ status = ap_scan_script_header_err_strs(r, NULL, NULL,
+ &termarg, buffer, NULL);
+
+ /* code below from mod_cgi.c */
+ location = apr_table_get(r->headers_out, "Location");
+
+ if (location && (location[0] == '/') && (r->status == 200)) {
+ r->method = apr_pstrdup(r->pool, "GET");
+ r->method_number = M_GET;
+
+ /* We already read the message body (if any), so don't allow
+ * the redirected request to think it has one. We can ignore
+ * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
+ */
+ apr_table_unset(r->headers_in, "Content-Length");
+
+ ap_internal_redirect_handler(location, r);
+
+ return OK;
+ }
+ else if (location && (r->status == 200)) {
+ MP_dRCFG;
+
+ /* Note that if a script wants to produce its own Redirect
+ * body, it now has to explicitly *say* "Status: 302"
+ */
+
+ /* XXX: this is a hack.
+ * filter return value doesn't seem to impact anything.
+ */
+ rcfg->status = HTTP_MOVED_TEMPORARILY;
+
+ return HTTP_MOVED_TEMPORARILY;
+ }
+
+ return status;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_cgi.h b/2_0_13/src/modules/perl/modperl_cgi.h
new file mode 100644
index 0000000..4924257
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_cgi.h
@@ -0,0 +1,45 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_CGI_H
+#define MODPERL_CGI_H
+
+/**
+ * split the HTTP headers from the body (if any) and feed them to
+ * Apache. Populate the pointer to the remaining data in the buffer
+ * (body if any or NULL)
+ *
+ * @param r request_rec
+ * @param buffer a string with headers and potentially body
+ * (could be non-null terminated)
+ * @param len length of 'buffer' on entry
+ * length of 'body' on return
+ * @param body pointer to the body within the 'buffer' on return
+ * NULL if the buffer contained only headers
+ *
+ * @return status
+ */
+MP_INLINE int modperl_cgi_header_parse(request_rec *r, char *buffer,
+ apr_size_t *len, const char **body);
+
+#endif /* MODPERL_CGI_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_cmd.c b/2_0_13/src/modules/perl/modperl_cmd.c
new file mode 100644
index 0000000..5b28771
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_cmd.c
@@ -0,0 +1,822 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* This ensures that a given directive is either in Server context
+ * or in a .htaccess file, usefull for things like PerlRequire
+ */
+#define MP_CHECK_SERVER_OR_HTACCESS_CONTEXT \
+ if (parms->path && (parms->override & ACCESS_CONF)) { \
+ ap_directive_t *d = parms->directive; \
+ return apr_psprintf(parms->pool, \
+ "%s directive not allowed in a %s> block", \
+ d->directive, \
+ d->parent->directive); \
+ }
+
+static char *modperl_cmd_unclosed_directive(cmd_parms *parms)
+{
+ return apr_pstrcat(parms->pool, parms->cmd->name,
+ "> directive missing closing '>'", NULL);
+}
+
+static char *modperl_cmd_too_late(cmd_parms *parms)
+{
+ return apr_pstrcat(parms->pool, "mod_perl is already running, "
+ "too late for ", parms->cmd->name, NULL);
+}
+
+char *modperl_cmd_push_handlers(MpAV **handlers, const char *name,
+ apr_pool_t *p)
+{
+ modperl_handler_t *h = modperl_handler_new(p, name);
+
+ if (!*handlers) {
+ *handlers = modperl_handler_array_new(p);
+ MP_TRACE_d(MP_FUNC, "created handler stack");
+ }
+
+ /* XXX parse_handler if Perl is running */
+
+ modperl_handler_array_push(*handlers, h);
+ MP_TRACE_d(MP_FUNC, "pushed handler: %s", h->name);
+
+ return NULL;
+}
+
+char *modperl_cmd_push_filter_handlers(MpAV **handlers,
+ const char *name,
+ apr_pool_t *p)
+{
+ modperl_handler_t *h = modperl_handler_new(p, name);
+
+ /* filter modules need to be autoloaded, because their attributes
+ * need to be known long before the callback is issued
+ */
+ if (*name == '-') {
+ MP_TRACE_h(MP_FUNC,
+ "warning: filter handler %s will be not autoloaded. "
+ "Unless the module defining this handler is explicitly "
+ "preloaded, filter attributes will be ignored.");
+ }
+ else {
+ MpHandlerAUTOLOAD_On(h);
+ MP_TRACE_h(MP_FUNC,
+ "filter handler %s will be autoloaded (to make "
+ "the filter attributes available)", h->name);
+ }
+
+ if (!*handlers) {
+ *handlers = modperl_handler_array_new(p);
+ MP_TRACE_d(MP_FUNC, "created handler stack");
+ }
+
+ modperl_handler_array_push(*handlers, h);
+ MP_TRACE_d(MP_FUNC, "pushed httpd filter handler: %s", h->name);
+
+ return NULL;
+}
+
+static char *modperl_cmd_push_httpd_filter_handlers(MpAV **handlers,
+ const char *name,
+ apr_pool_t *p)
+{
+ modperl_handler_t *h = modperl_handler_new(p, name);
+
+ /* this is not a real mod_perl handler, we just re-use the
+ * handlers structure to be able to mix mod_perl and non-mod_perl
+ * filters */
+ MpHandlerFAKE_On(h);
+ h->attrs = MP_FILTER_HTTPD_HANDLER;
+
+ if (!*handlers) {
+ *handlers = modperl_handler_array_new(p);
+ MP_TRACE_d(MP_FUNC, "created handler stack");
+ }
+
+ modperl_handler_array_push(*handlers, h);
+ MP_TRACE_d(MP_FUNC, "pushed httpd filter handler: %s", h->name);
+
+ return NULL;
+}
+
+
+#define MP_CMD_SRV_TRACE \
+ MP_TRACE_d(MP_FUNC, "%s %s", parms->cmd->name, arg)
+
+#define MP_CMD_SRV_CHECK \
+MP_CMD_SRV_TRACE; \
+{ \
+ const char *err = ap_check_cmd_context(parms, GLOBAL_ONLY); \
+ if (err) return err; \
+}
+
+MP_CMD_SRV_DECLARE(trace)
+{
+ MP_CMD_SRV_CHECK;
+ modperl_trace_level_set_apache(parms->server, arg);
+ return NULL;
+}
+
+/* this test shows whether the perl for the current s is running
+ * (either base or vhost) */
+static int modperl_vhost_is_running(server_rec *s)
+{
+#ifdef USE_ITHREADS
+ if (s->is_virtual){
+ MP_dSCFG(s);
+ return scfg->mip ? TRUE : FALSE;
+ }
+#endif
+
+ return modperl_is_running();
+
+}
+
+MP_CMD_SRV_DECLARE(switches)
+{
+ server_rec *s = parms->server;
+ MP_dSCFG(s);
+ if (modperl_vhost_is_running(s)) {
+ return modperl_cmd_too_late(parms);
+ }
+ MP_TRACE_d(MP_FUNC, "arg = %s", arg);
+
+ if (!strncasecmp(arg, "+inherit", 8)) {
+ modperl_cmd_options(parms, mconfig, "+InheritSwitches");
+ }
+ else {
+ modperl_config_srv_argv_push(arg);
+ }
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE(modules)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ MP_PERL_CONTEXT_DECLARE;
+
+ MP_CHECK_SERVER_OR_HTACCESS_CONTEXT;
+
+ if (modperl_is_running() &&
+ modperl_init_vhost(parms->server, parms->pool, NULL) != OK)
+ {
+ return "init mod_perl vhost failed";
+ }
+
+ if (modperl_is_running()) {
+ char *error = NULL;
+
+ MP_TRACE_d(MP_FUNC, "load PerlModule %s", arg);
+
+ MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
+ if (!modperl_require_module(aTHX_ arg, FALSE)) {
+ error = SvPVX(ERRSV);
+ }
+ else {
+ modperl_env_sync_srv_env_hash2table(aTHX_ parms->pool, scfg);
+ modperl_env_sync_dir_env_hash2table(aTHX_ parms->pool, dcfg);
+ }
+ MP_PERL_CONTEXT_RESTORE;
+
+ return error;
+ }
+ else {
+ MP_TRACE_d(MP_FUNC, "push PerlModule %s", arg);
+ *(const char **)apr_array_push(scfg->PerlModule) = arg;
+ return NULL;
+ }
+}
+
+MP_CMD_SRV_DECLARE(requires)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ MP_PERL_CONTEXT_DECLARE;
+
+ MP_CHECK_SERVER_OR_HTACCESS_CONTEXT;
+
+ if (modperl_is_running() &&
+ modperl_init_vhost(parms->server, parms->pool, NULL) != OK)
+ {
+ return "init mod_perl vhost failed";
+ }
+
+ if (modperl_is_running()) {
+ char *error = NULL;
+
+ MP_TRACE_d(MP_FUNC, "load PerlRequire %s", arg);
+
+ MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
+ if (!modperl_require_file(aTHX_ arg, FALSE)) {
+ error = SvPVX(ERRSV);
+ }
+ else {
+ modperl_env_sync_srv_env_hash2table(aTHX_ parms->pool, scfg);
+ modperl_env_sync_dir_env_hash2table(aTHX_ parms->pool, dcfg);
+ }
+ MP_PERL_CONTEXT_RESTORE;
+
+ return error;
+ }
+ else {
+ MP_TRACE_d(MP_FUNC, "push PerlRequire %s", arg);
+ *(const char **)apr_array_push(scfg->PerlRequire) = arg;
+ return NULL;
+ }
+}
+
+MP_CMD_SRV_DECLARE(config_requires)
+{
+ /* we must init earlier than normal */
+ modperl_run();
+
+ /* PerlConfigFile is only different from PerlRequires by forcing
+ * an immediate init.
+ */
+ return modperl_cmd_requires(parms, mconfig, arg);
+}
+
+MP_CMD_SRV_DECLARE(post_config_requires)
+{
+ apr_pool_t *p = parms->temp_pool;
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ MP_dSCFG(parms->server);
+
+ modperl_require_file_t *require = apr_pcalloc(p, sizeof(*require));
+ MP_TRACE_d(MP_FUNC, "push PerlPostConfigRequire for %s", arg);
+ require->file = arg;
+ require->dcfg = dcfg;
+
+ *(modperl_require_file_t **)
+ apr_array_push(scfg->PerlPostConfigRequire) = require;
+
+ return NULL;
+}
+
+static void modperl_cmd_addvar_func(apr_table_t *configvars,
+ apr_table_t *setvars,
+ const char *key, const char *val)
+{
+ apr_table_addn(configvars, key, val);
+}
+
+/* Conceptually, setvar is { unsetvar; addvar; } */
+
+static void modperl_cmd_setvar_func(apr_table_t *configvars,
+ apr_table_t *setvars,
+ const char * key, const char *val)
+{
+ apr_table_setn(setvars, key, val);
+ apr_table_setn(configvars, key, val);
+}
+
+static const char *modperl_cmd_modvar(modperl_var_modify_t varfunc,
+ cmd_parms *parms,
+ modperl_config_dir_t *dcfg,
+ const char *arg1, const char *arg2)
+{
+ varfunc(dcfg->configvars, dcfg->setvars, arg1, arg2);
+
+ MP_TRACE_d(MP_FUNC, "%s DIR: arg1 = %s, arg2 = %s",
+ parms->cmd->name, arg1, arg2);
+
+ /* make available via Apache2->server->dir_config */
+ if (!parms->path) {
+ MP_dSCFG(parms->server);
+ varfunc(scfg->configvars, scfg->setvars, arg1, arg2);
+
+ MP_TRACE_d(MP_FUNC, "%s SRV: arg1 = %s, arg2 = %s",
+ parms->cmd->name, arg1, arg2);
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE2(add_var)
+{
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ return modperl_cmd_modvar(modperl_cmd_addvar_func, parms, dcfg, arg1, arg2);
+}
+
+MP_CMD_SRV_DECLARE2(set_var)
+{
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ return modperl_cmd_modvar(modperl_cmd_setvar_func, parms, dcfg, arg1, arg2);
+}
+
+MP_CMD_SRV_DECLARE2(set_env)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+
+#ifdef ENV_IS_CASELESS /* i.e. WIN32 */
+ /* we turn off env magic during hv_store later, so do this now,
+ * else lookups on keys with lowercase characters will fails
+ * because Perl will uppercase them prior to lookup.
+ */
+ modperl_str_toupper((char *)arg1);
+#endif
+
+ MP_TRACE_d(MP_FUNC, "arg1 = %s, arg2 = %s", arg1, arg2);
+
+ if (!parms->path) {
+ /* will be propagated to environ */
+ apr_table_setn(scfg->SetEnv, arg1, arg2);
+ /* sync SetEnv => %ENV only for the top-level values */
+ if (modperl_vhost_is_running(parms->server)) {
+ MP_PERL_CONTEXT_DECLARE;
+ MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
+ modperl_env_hv_store(aTHX_ arg1, arg2);
+ MP_PERL_CONTEXT_RESTORE;
+ }
+ }
+
+ apr_table_setn(dcfg->SetEnv, arg1, arg2);
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE(pass_env)
+{
+ MP_dSCFG(parms->server);
+ char *val = getenv(arg);
+
+#ifdef ENV_IS_CASELESS /* i.e. WIN32 */
+ /* we turn off env magic during hv_store later, so do this now,
+ * else lookups on keys with lowercase characters will fails
+ * because Perl will uppercase them prior to lookup.
+ */
+ modperl_str_toupper((char *)arg);
+#endif
+
+ if (val) {
+ apr_table_setn(scfg->PassEnv, arg, apr_pstrdup(parms->pool, val));
+ if (modperl_vhost_is_running(parms->server)) {
+ MP_PERL_CONTEXT_DECLARE;
+ MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
+ modperl_env_hv_store(aTHX_ arg, val);
+ MP_PERL_CONTEXT_RESTORE;
+ }
+ MP_TRACE_d(MP_FUNC, "arg = %s, val = %s", arg, val);
+ }
+ else {
+ MP_TRACE_d(MP_FUNC, "arg = %s: not found via getenv()", arg);
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE(options)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ int is_per_dir = parms->path ? 1 : 0;
+ modperl_options_t *opts = is_per_dir ? dcfg->flags : scfg->flags;
+ apr_pool_t *p = parms->temp_pool;
+ const char *error;
+
+ MP_TRACE_d(MP_FUNC, "arg = %s", arg);
+ if ((error = modperl_options_set(p, opts, arg)) && !is_per_dir) {
+ /* maybe a per-directory option outside of a container */
+ if (modperl_options_set(p, dcfg->flags, arg) == NULL) {
+ error = NULL;
+ }
+ }
+
+ if (error) {
+ return error;
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE(init_handlers)
+{
+ if (parms->path) {
+ return modperl_cmd_header_parser_handlers(parms, mconfig, arg);
+ }
+
+ return modperl_cmd_post_read_request_handlers(parms, mconfig, arg);
+}
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+
+MP_CMD_SRV_DECLARE2(authz_provider)
+{
+ apr_pool_t *p = parms->pool;
+ char *name = apr_pstrdup(p, arg1);
+ char *cb = apr_pstrdup(p, arg2);
+
+ modperl_register_auth_provider_name(p, AUTHZ_PROVIDER_GROUP, name,
+ AUTHZ_PROVIDER_VERSION, cb, NULL,
+ AP_AUTH_INTERNAL_PER_CONF);
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE2(authn_provider)
+{
+ apr_pool_t *p = parms->pool;
+ char *name = apr_pstrdup(p, arg1);
+ char *cb = apr_pstrdup(p, arg2);
+
+ modperl_register_auth_provider_name(p, AUTHN_PROVIDER_GROUP, name,
+ AUTHN_PROVIDER_VERSION, cb, NULL,
+ AP_AUTH_INTERNAL_PER_CONF);
+ return NULL;
+}
+
+#endif
+
+static const char *modperl_cmd_parse_args(apr_pool_t *p,
+ const char *args,
+ apr_table_t **t)
+{
+ const char *orig_args = args;
+ char *pair, *key, *val;
+ *t = apr_table_make(p, 2);
+
+ while (*(pair = ap_getword(p, &args, ',')) != '\0') {
+ key = ap_getword_nc(p, &pair, '=');
+ val = pair;
+
+ if (!(*key && *val)) {
+ return apr_pstrcat(p, "invalid args spec: ",
+ orig_args, NULL);
+ }
+
+ apr_table_set(*t, key, val);
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE(perl)
+{
+ apr_pool_t *p = parms->pool;
+ const char *endp = ap_strrchr_c(arg, '>');
+ const char *errmsg;
+ char *code = "";
+ char line[MAX_STRING_LEN];
+ apr_table_t *args;
+ ap_directive_t **current = mconfig;
+ int line_num;
+
+ if (!endp) {
+ return modperl_cmd_unclosed_directive(parms);
+ }
+
+ MP_CHECK_SERVER_OR_HTACCESS_CONTEXT;
+
+ arg = apr_pstrndup(p, arg, endp - arg);
+
+ if ((errmsg = modperl_cmd_parse_args(p, arg, &args))) {
+ return errmsg;
+ }
+
+ line_num = parms->config_file->line_number+1;
+ while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) {
+ /*XXX: Not sure how robust this is */
+ if (strEQ(line, "</Perl>")) {
+ break;
+ }
+
+ /*XXX: Less than optimal */
+ code = apr_pstrcat(p, code, line, "\n", NULL);
+ }
+
+ /* Here, we have to replace our current config node for the next pass */
+ if (!*current) {
+ *current = apr_pcalloc(p, sizeof(**current));
+ }
+
+ (*current)->filename = parms->config_file->name;
+ (*current)->line_num = line_num;
+ (*current)->directive = apr_pstrdup(p, "Perl");
+ (*current)->args = code;
+ (*current)->data = args;
+
+ return NULL;
+}
+
+#define MP_DEFAULT_PERLSECTION_HANDLER "Apache2::PerlSections"
+#define MP_DEFAULT_PERLSECTION_PACKAGE "Apache2::ReadConfig"
+#define MP_PERLSECTIONS_SAVECONFIG_SV \
+ get_sv("Apache2::PerlSections::Save", FALSE)
+#define MP_PERLSECTIONS_SERVER_SV \
+ get_sv("Apache2::PerlSections::Server", TRUE)
+
+MP_CMD_SRV_DECLARE(perldo)
+{
+ apr_pool_t *p = parms->pool;
+ server_rec *s = parms->server;
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ apr_table_t *options;
+ modperl_handler_t *handler = NULL;
+ const char *pkg_name = NULL;
+ ap_directive_t *directive = parms->directive;
+ MP_dSCFG(s);
+ MP_PERL_CONTEXT_DECLARE;
+
+ if (!(arg && *arg)) {
+ return NULL;
+ }
+
+ MP_CHECK_SERVER_OR_HTACCESS_CONTEXT;
+
+ /* we must init earlier than normal */
+ modperl_run();
+
+ if (modperl_init_vhost(s, p, NULL) != OK) {
+ return "init mod_perl vhost failed";
+ }
+
+ MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
+
+ /* data will be set by a <Perl> section */
+ if ((options = directive->data)) {
+ const char *pkg_namespace;
+ const char *pkg_base;
+ const char *handler_name;
+ const char *line_header;
+
+ if (!(handler_name = apr_table_get(options, "handler"))) {
+ handler_name = apr_pstrdup(p, MP_DEFAULT_PERLSECTION_HANDLER);
+ apr_table_set(options, "handler", handler_name);
+ }
+
+ handler = modperl_handler_new(p, handler_name);
+
+ if (!(pkg_base = apr_table_get(options, "package"))) {
+ pkg_base = apr_pstrdup(p, MP_DEFAULT_PERLSECTION_PACKAGE);
+ }
+
+ pkg_namespace = modperl_file2package(p, directive->filename);
+
+ pkg_name = apr_psprintf(p, "%s::%s::line_%d",
+ pkg_base,
+ pkg_namespace,
+ directive->line_num);
+
+ apr_table_set(options, "package", pkg_name);
+
+ line_header = apr_psprintf(p, "\n#line %d %s\n",
+ directive->line_num,
+ directive->filename);
+
+ /* put the code about to be executed in the configured package */
+ arg = apr_pstrcat(p, "package ", pkg_name, ";", line_header,
+ arg, NULL);
+ }
+
+#ifdef USE_ITHREADS
+ MP_TRACE_i(MP_FUNC, "using interp %lx to execute perl section:\n%s",
+ scfg->mip->parent, arg);
+#endif
+
+ {
+ SV *server = MP_PERLSECTIONS_SERVER_SV;
+ SV *code = newSVpv(arg, 0);
+ GV *gv = gv_fetchpv("0", TRUE, SVt_PV);
+ ENTER;SAVETMPS;
+ save_scalar(gv); /* local $0 */
+#if MP_PERL_VERSION_AT_LEAST(5, 9, 0)
+ TAINT_NOT; /* XXX: temp workaround, see my p5p post */
+#endif
+ sv_setref_pv(server, "Apache2::ServerRec", (void*)s);
+ sv_setpv_mg(GvSV(gv), directive->filename);
+ eval_sv(code, G_SCALAR|G_KEEPERR);
+ SvREFCNT_dec(code);
+ modperl_env_sync_srv_env_hash2table(aTHX_ p, scfg);
+ modperl_env_sync_dir_env_hash2table(aTHX_ p, dcfg);
+ FREETMPS;LEAVE;
+ }
+
+ if (SvTRUE(ERRSV)) {
+ MP_PERL_CONTEXT_RESTORE;
+ return SvPVX(ERRSV);
+ }
+
+ if (handler) {
+ int status;
+ SV *saveconfig = MP_PERLSECTIONS_SAVECONFIG_SV;
+ AV *args = (AV *)NULL;
+
+ modperl_handler_make_args(aTHX_ &args,
+ "Apache2::CmdParms", parms,
+ "APR::Table", options,
+ NULL);
+
+ status = modperl_callback(aTHX_ handler, p, NULL, s, args);
+
+ SvREFCNT_dec((SV*)args);
+
+ if (!(saveconfig && SvTRUE(saveconfig))) {
+ modperl_package_unload(aTHX_ pkg_name);
+ }
+
+ if (status != OK) {
+ char *error = SvTRUE(ERRSV) ? SvPVX(ERRSV) :
+ apr_psprintf(p, "<Perl> handler %s failed with status=%d",
+ handler->name, status);
+ MP_PERL_CONTEXT_RESTORE;
+ return error;
+ }
+ }
+
+ MP_PERL_CONTEXT_RESTORE;
+ return NULL;
+}
+
+#define MP_POD_FORMAT(s) \
+ (ap_strstr_c(s, "httpd") || ap_strstr_c(s, "apache"))
+
+MP_CMD_SRV_DECLARE(pod)
+{
+ char line[MAX_STRING_LEN];
+
+ if (arg && *arg && !(MP_POD_FORMAT(arg) || strstr("pod", arg))) {
+ return "Unknown =back format";
+ }
+
+ while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) {
+ if (strEQ(line, "=cut")) {
+ break;
+ }
+ if (strnEQ(line, "=over", 5) && MP_POD_FORMAT(line)) {
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE(pod_cut)
+{
+ return "=cut without =pod";
+}
+
+MP_CMD_SRV_DECLARE(END)
+{
+ char line[MAX_STRING_LEN];
+
+ while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) {
+ /* soak up rest of the file */
+ }
+
+ return NULL;
+}
+
+/*
+ * XXX: the name of this directive may or may not stay.
+ * need a way to note that a module has config directives.
+ * don't want to start mod_perl when we see a non-special PerlModule.
+ */
+MP_CMD_SRV_DECLARE(load_module)
+{
+ const char *errmsg;
+
+ MP_TRACE_d(MP_FUNC, "PerlLoadModule %s", arg);
+
+ /* we must init earlier than normal */
+ modperl_run();
+
+ if ((errmsg = modperl_cmd_modules(parms, mconfig, arg))) {
+ return errmsg;
+ }
+
+ return NULL;
+}
+
+/* propogate filters insertion ala SetInputFilter */
+MP_CMD_SRV_DECLARE(set_input_filter)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ char *filter;
+
+ if (!MpSrvENABLE(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "Perl is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+ if (!MpSrvINPUT_FILTER(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "PerlSetInputFilter is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+
+ while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) {
+ modperl_cmd_push_httpd_filter_handlers(
+ &(dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER]),
+ filter, parms->pool);
+ }
+
+ return NULL;
+}
+
+/* propogate filters insertion ala SetOutputFilter */
+MP_CMD_SRV_DECLARE(set_output_filter)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ char *filter;
+
+ if (!MpSrvENABLE(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "Perl is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+ if (!MpSrvINPUT_FILTER(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "PerlSetOutputFilter is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+
+ while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) {
+ modperl_cmd_push_httpd_filter_handlers(
+ &(dcfg->handlers_per_dir[MP_OUTPUT_FILTER_HANDLER]),
+ filter, parms->pool);
+ }
+
+ return NULL;
+}
+
+
+#ifdef MP_COMPAT_1X
+
+MP_CMD_SRV_DECLARE_FLAG(taint_check)
+{
+ if (flag_on) {
+ return modperl_cmd_switches(parms, mconfig, "-T");
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE_FLAG(warn)
+{
+ if (flag_on) {
+ return modperl_cmd_switches(parms, mconfig, "-w");
+ }
+
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE_FLAG(send_header)
+{
+ char *arg = flag_on ? "+ParseHeaders" : "-ParseHeaders";
+ return modperl_cmd_options(parms, mconfig, arg);
+}
+
+MP_CMD_SRV_DECLARE_FLAG(setup_env)
+{
+ char *arg = flag_on ? "+SetupEnv" : "-SetupEnv";
+ return modperl_cmd_options(parms, mconfig, arg);
+}
+
+#endif /* MP_COMPAT_1X */
+
+#ifdef USE_ITHREADS
+
+#define MP_CMD_INTERP_POOL_IMP(xitem) \
+const char *modperl_cmd_interp_##xitem(cmd_parms *parms, \
+ void *mconfig, const char *arg) \
+{ \
+ MP_dSCFG(parms->server); \
+ int item = atoi(arg); \
+ scfg->interp_pool_cfg->xitem = item; \
+ MP_TRACE_d(MP_FUNC, "%s %d", parms->cmd->name, item); \
+ return NULL; \
+}
+
+MP_CMD_INTERP_POOL_IMP(start);
+MP_CMD_INTERP_POOL_IMP(max);
+MP_CMD_INTERP_POOL_IMP(max_spare);
+MP_CMD_INTERP_POOL_IMP(min_spare);
+MP_CMD_INTERP_POOL_IMP(max_requests);
+
+#endif /* USE_ITHREADS */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_cmd.h b/2_0_13/src/modules/perl/modperl_cmd.h
new file mode 100644
index 0000000..883259d
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_cmd.h
@@ -0,0 +1,150 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_CMD_H
+#define MODPERL_CMD_H
+
+char *modperl_cmd_push_handlers(MpAV **handlers, const char *name,
+ apr_pool_t *p);
+
+char *modperl_cmd_push_filter_handlers(MpAV **handlers,
+ const char *name,
+ apr_pool_t *p);
+
+#define MP_CMD_SRV_DECLARE(item) \
+ const char *modperl_cmd_##item(cmd_parms *parms, void *mconfig, \
+ const char *arg)
+
+#define MP_CMD_SRV_DECLARE2(item) \
+ const char *modperl_cmd_##item(cmd_parms *parms, void *mconfig, \
+ const char *arg1, const char *arg2)
+
+#define MP_CMD_SRV_DECLARE_FLAG(item) \
+ const char *modperl_cmd_##item(cmd_parms *parms, \
+ void *mconfig, int flag_on)
+
+MP_CMD_SRV_DECLARE(trace);
+MP_CMD_SRV_DECLARE(switches);
+MP_CMD_SRV_DECLARE(modules);
+MP_CMD_SRV_DECLARE(requires);
+MP_CMD_SRV_DECLARE(config_requires);
+MP_CMD_SRV_DECLARE(post_config_requires);
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+MP_CMD_SRV_DECLARE2(authz_provider);
+MP_CMD_SRV_DECLARE2(authn_provider);
+#endif
+MP_CMD_SRV_DECLARE2(set_var);
+MP_CMD_SRV_DECLARE2(add_var);
+MP_CMD_SRV_DECLARE2(set_env);
+MP_CMD_SRV_DECLARE(pass_env);
+MP_CMD_SRV_DECLARE(options);
+MP_CMD_SRV_DECLARE(init_handlers);
+MP_CMD_SRV_DECLARE(perl);
+MP_CMD_SRV_DECLARE(perldo);
+MP_CMD_SRV_DECLARE(pod);
+MP_CMD_SRV_DECLARE(pod_cut);
+MP_CMD_SRV_DECLARE(END);
+MP_CMD_SRV_DECLARE(load_module);
+MP_CMD_SRV_DECLARE(set_input_filter);
+MP_CMD_SRV_DECLARE(set_output_filter);
+
+#ifdef MP_COMPAT_1X
+
+MP_CMD_SRV_DECLARE_FLAG(taint_check);
+MP_CMD_SRV_DECLARE_FLAG(warn);
+MP_CMD_SRV_DECLARE_FLAG(send_header);
+MP_CMD_SRV_DECLARE_FLAG(setup_env);
+
+#endif /* MP_COMPAT_1X */
+
+#ifdef USE_ITHREADS
+MP_CMD_SRV_DECLARE(interp_start);
+MP_CMD_SRV_DECLARE(interp_max);
+MP_CMD_SRV_DECLARE(interp_max_spare);
+MP_CMD_SRV_DECLARE(interp_min_spare);
+MP_CMD_SRV_DECLARE(interp_max_requests);
+
+#endif /* USE_ITHREADS */
+
+#define MP_CMD_SRV_RAW_ARGS(name, item, desc) \
+ AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
+#define MP_CMD_SRV_RAW_ARGS_ON_READ(name, item, desc) \
+ AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF|EXEC_ON_READ, desc )
+
+#define MP_CMD_SRV_FLAG(name, item, desc) \
+ AP_INIT_FLAG( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
+#define MP_CMD_SRV_TAKE1(name, item, desc) \
+ AP_INIT_TAKE1( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
+#define MP_CMD_SRV_TAKE2(name, item, desc) \
+ AP_INIT_TAKE2( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
+#define MP_CMD_SRV_ITERATE(name, item, desc) \
+ AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
+#define MP_CMD_SRV_ITERATE_ON_READ(name, item, desc) \
+ AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF|EXEC_ON_READ, desc )
+
+#define MP_CMD_SRV_ITERATE2(name, item, desc) \
+ AP_INIT_ITERATE2( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
+#define MP_CMD_DIR_TAKE1(name, item, desc) \
+ AP_INIT_TAKE1( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_TAKE2(name, item, desc) \
+ AP_INIT_TAKE2( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_ITERATE(name, item, desc) \
+ AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_ITERATE2(name, item, desc) \
+ AP_INIT_ITERATE2( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_FLAG(name, item, desc) \
+ AP_INIT_FLAG( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_RAW_ARGS(name, item, desc) \
+ AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_RAW_ARGS_ON_READ(name, item, desc) \
+ AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \
+ OR_ALL|EXEC_ON_READ, desc )
+
+#endif /* MODPERL_CMD_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_debug.c b/2_0_13/src/modules/perl/modperl_common_debug.c
new file mode 100644
index 0000000..4ae508e
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_debug.c
@@ -0,0 +1,26 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file must not contain any symbols from apache/mod_perl
+ * (apr and perl are OK) */
+#include "modperl_common_includes.h"
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_debug.h b/2_0_13/src/modules/perl/modperl_common_debug.h
new file mode 100644
index 0000000..342986b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_debug.h
@@ -0,0 +1,28 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_COMMON_DEBUG_H
+#define MODPERL_COMMON_DEBUG_H
+
+
+#endif /* MODPERL_COMMON_DEBUG_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_includes.h b/2_0_13/src/modules/perl/modperl_common_includes.h
new file mode 100644
index 0000000..971b2bd
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_includes.h
@@ -0,0 +1,34 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_COMMON_INCLUDES_H
+#define MODPERL_COMMON_INCLUDES_H
+
+/* header files which are independet of Apache/mod_perl */
+
+#include "modperl_apr_includes.h"
+#include "modperl_apr_compat.h"
+#include "modperl_perl_includes.h"
+#include "modperl_common_types.h"
+
+#endif /* MODPERL_COMMON_INCLUDES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_log.c b/2_0_13/src/modules/perl/modperl_common_log.c
new file mode 100644
index 0000000..3bdb359
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_log.c
@@ -0,0 +1,131 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_common_includes.h"
+#include "modperl_common_log.h"
+#include "modperl_debug.h"
+
+#undef getenv /* from XSUB.h */
+
+static apr_file_t *logfile = NULL;
+
+#ifdef WIN32
+static unsigned long debug_level = 0;
+#else
+unsigned long MP_debug_level = 0;
+#define debug_level MP_debug_level
+#endif
+
+unsigned long modperl_debug_level(void)
+{
+ return debug_level;
+}
+
+void modperl_trace_logfile_set(apr_file_t *logfile_new)
+{
+ logfile = logfile_new;
+}
+
+void modperl_trace(const char *func, const char *fmt, ...)
+{
+ char vstr[8192];
+ apr_size_t vstr_len = 0;
+ va_list args;
+
+ if (!logfile) {
+ return;
+ }
+
+ /* for more information on formatting codes see
+ http://apr.apache.org/docs/apr/1.4/group__apr__lib.html#gad2cd3594aeaafd45931d1034965f48c1
+ */
+
+#ifndef MP_IN_XS
+ /* PERL_GET_CONTEXT yields nonsense until the first interpreter is
+ * created. Hence the modperl_is_running() question. */
+ if (modperl_threaded_mpm()) {
+ if (modperl_threads_started()) {
+ apr_os_thread_t tid = apr_os_thread_current();
+ apr_file_printf(logfile, "[pid=%lu, tid=%pt, perl=%pp] ",
+ (unsigned long)getpid(), &tid,
+ modperl_is_running() ? PERL_GET_CONTEXT : NULL);
+ }
+ else {
+ apr_file_printf(logfile, "[pid=%lu, perl=%pp] ",
+ (unsigned long)getpid(),
+ modperl_is_running() ? PERL_GET_CONTEXT : NULL);
+ }
+ }
+ else {
+#ifdef USE_ITHREADS
+ apr_file_printf(logfile, "[pid=%lu, perl=%pp] ",
+ (unsigned long)getpid(),
+ modperl_is_running() ? PERL_GET_CONTEXT : NULL);
+#else
+ apr_file_printf(logfile, "[pid=%lu] ", (unsigned long)getpid());
+#endif
+ }
+#endif
+
+ if (func && *func) {
+ apr_file_printf(logfile, "%s: ", func);
+ }
+
+ va_start(args, fmt);
+ vstr_len = apr_vsnprintf(vstr, sizeof(vstr), fmt, args);
+ va_end(args);
+
+ apr_file_write(logfile, vstr, &vstr_len);
+ apr_file_printf(logfile, "\n");
+}
+
+void modperl_trace_level_set(apr_file_t *logfile, const char *level)
+{
+ if (!level) {
+ if (!(level = getenv("MOD_PERL_TRACE"))) {
+ return;
+ }
+ }
+ debug_level = 0x0;
+
+ if (strcasecmp(level, "all") == 0) {
+ debug_level = 0xffffffff;
+ }
+ else if (apr_isalpha(level[0])) {
+ static char debopts[] = MP_TRACE_OPTS;
+ char *d;
+
+ for (; *level && (d = strchr(debopts, *level)); level++) {
+ debug_level |= 1 << (d - debopts);
+ }
+ }
+ else {
+ debug_level = atoi(level);
+ }
+
+ debug_level |= 0x80000000;
+
+ modperl_trace_logfile_set(logfile);
+
+ MP_TRACE_any_do(MP_TRACE_dump_flags());
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_log.h b/2_0_13/src/modules/perl/modperl_common_log.h
new file mode 100644
index 0000000..46c9491
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_log.h
@@ -0,0 +1,67 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_COMMON_LOG_H
+#define MODPERL_COMMON_LOG_H
+
+#define MP_STRINGIFY(n) MP_STRINGIFY_HELPER(n)
+#define MP_STRINGIFY_HELPER(n) #n
+
+# if defined(__GNUC__)
+# if (__GNUC__ > 2)
+# define MP_FUNC __func__
+# else
+# define MP_FUNC __FUNCTION__
+# endif
+# else
+# define MP_FUNC __FILE__ ":" MP_STRINGIFY(__LINE__)
+# endif
+
+#include "modperl_apr_includes.h"
+#include "apr_lib.h"
+#include "modperl_trace.h"
+
+#ifdef _PTHREAD_H
+#define modperl_thread_self() pthread_self()
+#else
+#define modperl_thread_self() 0
+#endif
+
+#define MP_TIDF \
+(unsigned long)modperl_thread_self()
+
+void modperl_trace_logfile_set(apr_file_t *logfile_new);
+
+unsigned long modperl_debug_level(void);
+
+#ifdef WIN32
+#define MP_debug_level modperl_debug_level()
+#else
+extern unsigned long MP_debug_level;
+#endif
+
+void modperl_trace(const char *func, const char *fmt, ...);
+
+void modperl_trace_level_set(apr_file_t *logfile, const char *level);
+
+#endif /* MODPERL_COMMON_LOG_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_types.h b/2_0_13/src/modules/perl/modperl_common_types.h
new file mode 100644
index 0000000..bb4eb6c
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_types.h
@@ -0,0 +1,35 @@
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_COMMON_TYPES_H
+#define MODPERL_COMMON_TYPES_H
+
+/* subclass apr_uri_t */
+typedef struct {
+ apr_uri_t uri;
+ apr_pool_t *pool;
+ char *path_info;
+} modperl_uri_t;
+
+#endif /* MODPERL_COMMON_TYPES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_util.c b/2_0_13/src/modules/perl/modperl_common_util.c
new file mode 100644
index 0000000..c5f285f
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_util.c
@@ -0,0 +1,161 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file must not contain any symbols from apache/mod_perl (apr
+ * and perl are OK). Also try to keep all the mod_perl specific
+ * functions (even if they don't contain symbols from apache/mod_perl
+ * on in modperl_util.c, unless we want them elsewhere. That is
+ * needed in order to keep the libraries used outside mod_perl
+ * small */
+
+#include "modperl_common_util.h"
+
+/* Prefetch magic requires perl 5.8 */
+#if MP_PERL_VERSION_AT_LEAST(5, 8, 0)
+
+/* A custom MGVTBL with mg_copy slot filled in allows us to FETCH a
+ * table entry immediately during iteration. For multivalued keys
+ * this is essential in order to get the value corresponding to the
+ * current key, otherwise values() will always report the first value
+ * repeatedly. With this MGVTBL the keys() list always matches up
+ * with the values() list, even in the multivalued case. We only
+ * prefetch the value during iteration, because the prefetch adds
+ * overhead (an unnecessary FETCH call) to EXISTS and STORE
+ * operations. This way they are only "penalized" when the perl
+ * program is iterating via each(), which seems to be a reasonable
+ * tradeoff.
+ */
+
+MP_INLINE static
+int modperl_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv,
+ const char *name, int namelen)
+{
+ /* prefetch the value whenever we're iterating over the keys */
+ MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem);
+ SV *obj = SvRV(tie_magic->mg_obj);
+ if (SvCUR(obj)) {
+ SvGETMAGIC(nsv);
+ }
+ return 0;
+}
+
+
+static const MGVTBL modperl_table_magic_prefetch = {0, 0, 0, 0, 0,
+ modperl_table_magic_copy};
+#endif /* End of prefetch magic */
+
+MP_INLINE SV *modperl_hash_tie(pTHX_
+ const char *classname,
+ SV *tsv, void *p)
+{
+ SV *hv = (SV*)newHV();
+ SV *rsv = sv_newmortal();
+
+ sv_setref_pv(rsv, classname, p);
+
+ /* Prefetch magic requires perl 5.8 */
+#if MP_PERL_VERSION_AT_LEAST(5, 8, 0)
+
+ sv_magicext(hv, NULL, PERL_MAGIC_ext, NULL, (char *)NULL, -1);
+ SvMAGIC(hv)->mg_virtual = (MGVTBL *)&modperl_table_magic_prefetch;
+ SvMAGIC(hv)->mg_flags |= MGf_COPY;
+
+#endif /* End of prefetch magic */
+
+ sv_magic(hv, rsv, PERL_MAGIC_tied, (char *)NULL, 0);
+
+ return SvREFCNT_inc(sv_bless(sv_2mortal(newRV_noinc(hv)),
+ gv_stashpv(classname, TRUE)));
+}
+
+MP_INLINE SV *modperl_hash_tied_object_rv(pTHX_
+ const char *classname,
+ SV *tsv)
+{
+ if (sv_derived_from(tsv, classname)) {
+ if (SVt_PVHV == SvTYPE(SvRV(tsv))) {
+ SV *hv = SvRV(tsv);
+ MAGIC *mg;
+
+ if (SvMAGICAL(hv)) {
+ if ((mg = mg_find(hv, PERL_MAGIC_tied))) {
+ return mg->mg_obj;
+ }
+ else {
+ Perl_warn(aTHX_ "Not a tied hash: (magic=%c)", mg->mg_type);
+ }
+ }
+ else {
+ Perl_warn(aTHX_ "SV is not tied");
+ }
+ }
+ else {
+ return tsv;
+ }
+ }
+ else {
+ Perl_croak(aTHX_
+ "argument is not a blessed reference "
+ "(expecting an %s derived object)", classname);
+ }
+
+ return &PL_sv_undef;
+}
+
+MP_INLINE void *modperl_hash_tied_object(pTHX_
+ const char *classname,
+ SV *tsv)
+{
+ SV *rv = modperl_hash_tied_object_rv(aTHX_ classname, tsv);
+ if (SvROK(rv)) {
+ return INT2PTR(void *, SvIVX(SvRV(rv)));
+ }
+ else {
+ return NULL;
+ }
+}
+
+/* same as Symbol::gensym() */
+SV *modperl_perl_gensym(pTHX_ char *pack)
+{
+ GV *gv = newGVgen(pack);
+ SV *rv = newRV((SV*)gv);
+ (void)hv_delete(gv_stashpv(pack, TRUE),
+ GvNAME(gv), GvNAMELEN(gv), G_DISCARD);
+ return rv;
+}
+
+/* XXX: sv_setref_uv does not exist in 5.6.x */
+MP_INLINE SV *modperl_perl_sv_setref_uv(pTHX_ SV *rv,
+ const char *classname, UV uv)
+{
+ sv_setuv(newSVrv(rv, classname), uv);
+ return rv;
+}
+
+MP_INLINE modperl_uri_t *modperl_uri_new(apr_pool_t *p)
+{
+ modperl_uri_t *uri = (modperl_uri_t *)apr_pcalloc(p, sizeof(*uri));
+ uri->pool = p;
+ return uri;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_common_util.h b/2_0_13/src/modules/perl/modperl_common_util.h
new file mode 100644
index 0000000..55f1600
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_common_util.h
@@ -0,0 +1,119 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_common_includes.h"
+
+#ifndef MODPERL_COMMON_UTIL_H
+#define MODPERL_COMMON_UTIL_H
+
+#ifdef MP_DEBUG
+#define MP_INLINE
+#else
+#define MP_INLINE APR_INLINE
+#endif
+
+#ifdef CYGWIN
+#define MP_STATIC
+#else
+#define MP_STATIC static
+#endif
+
+#ifdef WIN32
+# define MP_FUNC_T(name) (_stdcall *name)
+# define MP_FUNC_NONSTD_T(name) (*name)
+/* XXX: not all functions get inlined
+ * so its unclear what to and not to include in the .def files
+ */
+# undef MP_INLINE
+# define MP_INLINE
+#else
+# define MP_FUNC_T(name) (*name)
+# define MP_FUNC_NONSTD_T(name) (*name)
+#endif
+
+
+#define MP_SSTRLEN(string) (sizeof(string)-1)
+
+#ifndef strcaseEQ
+# define strcaseEQ(s1,s2) (!strcasecmp(s1,s2))
+#endif
+#ifndef strncaseEQ
+# define strncaseEQ(s1,s2,l) (!strncasecmp(s1,s2,l))
+#endif
+
+#ifndef SvCLASS
+#define SvCLASS(o) HvNAME(SvSTASH(SvRV(o)))
+#endif
+
+#define SvObjIV(o) SvIV((SV*)SvRV(o))
+#define MgObjIV(m) SvIV((SV*)SvRV(m->mg_obj))
+
+#define MP_SvGROW(sv, len) \
+ (void)SvUPGRADE(sv, SVt_PV); \
+ SvGROW(sv, len+1)
+
+#define MP_SvCUR_set(sv, len) \
+ SvCUR_set(sv, len); \
+ *SvEND(sv) = '\0'; \
+ SvPOK_only(sv)
+
+#define MP_magical_untie(sv, mg_flags) \
+ mg_flags = SvMAGICAL((SV*)sv); \
+ SvMAGICAL_off((SV*)sv)
+
+#define MP_magical_tie(sv, mg_flags) \
+ SvFLAGS((SV*)sv) |= mg_flags
+
+/* some wrapper macros to detect perl versions
+ * and prevent code clutter */
+#define MP_PERL_VERSION_AT_LEAST(r, v, s) \
+ (PERL_REVISION == r && \
+ ((PERL_VERSION == v && PERL_SUBVERSION > s-1) || PERL_VERSION > v))
+
+#define MP_PERL_VERSION_AT_MOST(r, v, s) \
+ (PERL_REVISION == r && \
+ (PERL_VERSION < v || (PERL_VERSION == v && PERL_SUBVERSION < s+1)))
+
+#define MP_PERL_VERSION(r, v, s) \
+ (PERL_REVISION == r && PERL_VERSION == v && PERL_SUBVERSION == s)
+
+/* tie %hash */
+MP_INLINE SV *modperl_hash_tie(pTHX_ const char *classname,
+ SV *tsv, void *p);
+
+/* tied %hash */
+MP_INLINE SV *modperl_hash_tied_object_rv(pTHX_
+ const char *classname,
+ SV *tsv);
+/* tied %hash */
+MP_INLINE void *modperl_hash_tied_object(pTHX_ const char *classname,
+ SV *tsv);
+
+MP_INLINE SV *modperl_perl_sv_setref_uv(pTHX_ SV *rv,
+ const char *classname, UV uv);
+
+MP_INLINE modperl_uri_t *modperl_uri_new(apr_pool_t *p);
+
+SV *modperl_perl_gensym(pTHX_ char *pack);
+
+#endif /* MODPERL_COMMON_UTIL_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_config.c b/2_0_13/src/modules/perl/modperl_config.c
new file mode 100644
index 0000000..6603065
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_config.c
@@ -0,0 +1,680 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+void *modperl_config_dir_create(apr_pool_t *p, char *dir)
+{
+ modperl_config_dir_t *dcfg = modperl_config_dir_new(p);
+
+ dcfg->location = dir;
+
+ MP_TRACE_d(MP_FUNC, "dir %s", dir);
+
+ return dcfg;
+}
+
+#define merge_item(item) \
+ mrg->item = add->item ? add->item : base->item
+
+static apr_table_t *modperl_table_overlap(apr_pool_t *p,
+ apr_table_t *base,
+ apr_table_t *add)
+{
+ /* take the base (parent) values, and override with add (child) values,
+ * generating a new table. entries in add but not in base will be
+ * added to the new table. all using core apr table routines.
+ *
+ * note that this is equivalent to apr_table_overlap except a new
+ * table is generated, which is required (otherwise we would clobber
+ * the existing parent or child configurations)
+ *
+ * note that this is *not* equivalent to apr_table_overlap, although
+ * I think it should be, because apr_table_overlap seems to clear
+ * its first argument when the tables have different pools. I think
+ * this is wrong -- rici
+ */
+ apr_table_t *merge = apr_table_overlay(p, base, add);
+
+ /* compress will squash each key to the last value in the table. this
+ * is acceptable for all tables that expect only a single value per key
+ * such as PerlPassEnv and PerlSetEnv. PerlSetVar/PerlAddVar get their
+ * own, non-standard, merge routines in merge_table_config_vars.
+ */
+ apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
+
+ return merge;
+}
+
+#define merge_table_overlap_item(item) \
+ mrg->item = modperl_table_overlap(p, base->item, add->item)
+
+static apr_table_t *merge_config_add_vars(apr_pool_t *p,
+ const apr_table_t *base,
+ const apr_table_t *unset,
+ const apr_table_t *add)
+{
+ apr_table_t *temp = apr_table_copy(p, base);
+
+ const apr_array_header_t *arr;
+ apr_table_entry_t *entries;
+ int i;
+
+ /* for each key in unset do apr_table_unset(temp, key); */
+ arr = apr_table_elts(unset);
+ entries = (apr_table_entry_t *)arr->elts;
+
+ /* hopefully this is faster than using apr_table_do */
+ for (i = 0; i < arr->nelts; i++) {
+ if (entries[i].key) {
+ apr_table_unset(temp, entries[i].key);
+ }
+ }
+
+ return apr_table_overlay(p, temp, add);
+}
+
+#define merge_handlers(merge_flag, array) \
+ if (merge_flag(mrg)) { \
+ mrg->array = modperl_handler_array_merge(p, \
+ base->array, \
+ add->array); \
+ } \
+ else { \
+ merge_item(array); \
+ }
+
+void *modperl_config_dir_merge(apr_pool_t *p, void *basev, void *addv)
+{
+ int i;
+ modperl_config_dir_t
+ *base = (modperl_config_dir_t *)basev,
+ *add = (modperl_config_dir_t *)addv,
+ *mrg = modperl_config_dir_new(p);
+
+ MP_TRACE_d(MP_FUNC, "basev==0x%lx, addv==0x%lx, mrg==0x%lx",
+ (unsigned long)basev, (unsigned long)addv,
+ (unsigned long)mrg);
+
+ mrg->flags = modperl_options_merge(p, base->flags, add->flags);
+
+ merge_item(location);
+
+ merge_table_overlap_item(SetEnv);
+
+ /* this is where we merge PerlSetVar and PerlAddVar together */
+ mrg->configvars = merge_config_add_vars(p,
+ base->configvars,
+ add->setvars, add->configvars);
+ merge_table_overlap_item(setvars);
+
+ /* XXX: check if Perl*Handler is disabled */
+ for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
+ merge_handlers(MpDirMERGE_HANDLERS, handlers_per_dir[i]);
+ }
+
+ return mrg;
+}
+
+modperl_config_req_t *modperl_config_req_new(request_rec *r)
+{
+ modperl_config_req_t *rcfg =
+ (modperl_config_req_t *)apr_pcalloc(r->pool, sizeof(*rcfg));
+
+ MP_TRACE_d(MP_FUNC, "0x%lx", (unsigned long)rcfg);
+
+ return rcfg;
+}
+
+modperl_config_con_t *modperl_config_con_new(conn_rec *c)
+{
+ modperl_config_con_t *ccfg =
+ (modperl_config_con_t *)apr_pcalloc(c->pool, sizeof(*ccfg));
+
+ MP_TRACE_d(MP_FUNC, "0x%lx", (unsigned long)ccfg);
+
+ return ccfg;
+}
+
+modperl_config_srv_t *modperl_config_srv_new(apr_pool_t *p, server_rec *s)
+{
+ modperl_config_srv_t *scfg = (modperl_config_srv_t *)
+ apr_pcalloc(p, sizeof(*scfg));
+
+ scfg->flags = modperl_options_new(p, MpSrvType);
+ MpSrvENABLE_On(scfg); /* mod_perl enabled by default */
+ MpSrvHOOKS_ALL_On(scfg); /* all hooks enabled by default */
+
+ scfg->PerlModule = apr_array_make(p, 2, sizeof(char *));
+ scfg->PerlRequire = apr_array_make(p, 2, sizeof(char *));
+ scfg->PerlPostConfigRequire =
+ apr_array_make(p, 1, sizeof(modperl_require_file_t *));
+
+ /* 2 arguments + NULL terminator */
+ scfg->argv = apr_array_make(p, 3, sizeof(char *));
+
+ scfg->setvars = apr_table_make(p, 2);
+ scfg->configvars = apr_table_make(p, 2);
+
+ scfg->PassEnv = apr_table_make(p, 2);
+ scfg->SetEnv = apr_table_make(p, 2);
+
+#ifdef MP_USE_GTOP
+ scfg->gtop = modperl_gtop_new(p);
+#endif
+
+ /* make sure httpd's argv[0] is the first argument so $0 is
+ * correctly connected to the real thing */
+ modperl_config_srv_argv_push(s->process->argv[0]);
+
+ MP_TRACE_d(MP_FUNC, "new scfg: 0x%lx", (unsigned long)scfg);
+
+ return scfg;
+}
+
+modperl_config_dir_t *modperl_config_dir_new(apr_pool_t *p)
+{
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)
+ apr_pcalloc(p, sizeof(modperl_config_dir_t));
+
+ dcfg->flags = modperl_options_new(p, MpDirType);
+
+ dcfg->setvars = apr_table_make(p, 2);
+ dcfg->configvars = apr_table_make(p, 2);
+
+ dcfg->SetEnv = apr_table_make(p, 2);
+
+ MP_TRACE_d(MP_FUNC, "new dcfg: 0x%lx", (unsigned long)dcfg);
+
+ return dcfg;
+}
+
+#ifdef MP_TRACE
+static void dump_argv(modperl_config_srv_t *scfg)
+{
+ int i;
+ char **argv = (char **)scfg->argv->elts;
+ modperl_trace(NULL, "modperl_config_srv_argv_init =>");
+ for (i=0; i<scfg->argv->nelts; i++) {
+ modperl_trace(NULL, " %d = %s", i, argv[i]);
+ }
+}
+#endif
+
+char **modperl_config_srv_argv_init(modperl_config_srv_t *scfg, int *argc)
+{
+ modperl_config_srv_argv_push("-e;0");
+
+ *argc = scfg->argv->nelts;
+
+ /* perl_parse() expects a NULL terminated argv array */
+ modperl_config_srv_argv_push(NULL);
+
+ MP_TRACE_g_do(dump_argv(scfg));
+
+ return (char **)scfg->argv->elts;
+}
+
+void *modperl_config_srv_create(apr_pool_t *p, server_rec *s)
+{
+ modperl_config_srv_t *scfg = modperl_config_srv_new(p, s);
+
+ if (!s->is_virtual) {
+
+ /* give a chance to MOD_PERL_TRACE env var to set
+ * PerlTrace. This place is the earliest point in mod_perl
+ * configuration parsing, when we have the server object
+ */
+ modperl_trace_level_set_apache(s, NULL);
+
+ /* Must store the global server record as early as possible,
+ * because if mod_perl happens to be started from within a
+ * vhost (e.g., PerlLoadModule) the base server record won't
+ * be available to vhost and things will blow up
+ */
+ modperl_init_globals(s, p);
+ }
+
+ MP_TRACE_d(MP_FUNC, "p=0x%lx, s=0x%lx, virtual=%d",
+ p, s, s->is_virtual);
+
+#ifdef USE_ITHREADS
+
+ scfg->interp_pool_cfg =
+ (modperl_tipool_config_t *)
+ apr_pcalloc(p, sizeof(*scfg->interp_pool_cfg));
+
+ /* XXX: determine reasonable defaults */
+ scfg->interp_pool_cfg->start = 3;
+ scfg->interp_pool_cfg->max_spare = 3;
+ scfg->interp_pool_cfg->min_spare = 3;
+ scfg->interp_pool_cfg->max = 5;
+ scfg->interp_pool_cfg->max_requests = 2000;
+#endif /* USE_ITHREADS */
+
+ scfg->server = s;
+
+ return scfg;
+}
+
+/* XXX: this is not complete */
+void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv)
+{
+ int i;
+ modperl_config_srv_t
+ *base = (modperl_config_srv_t *)basev,
+ *add = (modperl_config_srv_t *)addv,
+ *mrg = modperl_config_srv_new(p, add->server);
+
+ MP_TRACE_d(MP_FUNC, "basev==0x%lx, addv==0x%lx, mrg==0x%lx",
+ (unsigned long)basev, (unsigned long)addv,
+ (unsigned long)mrg);
+
+ merge_item(modules);
+ merge_item(PerlModule);
+ merge_item(PerlRequire);
+ merge_item(PerlPostConfigRequire);
+
+ merge_table_overlap_item(SetEnv);
+ merge_table_overlap_item(PassEnv);
+
+ /* this is where we merge PerlSetVar and PerlAddVar together */
+ mrg->configvars = merge_config_add_vars(p,
+ base->configvars,
+ add->setvars, add->configvars);
+ merge_table_overlap_item(setvars);
+
+ merge_item(server);
+
+#ifdef USE_ITHREADS
+ merge_item(interp_pool_cfg);
+#else
+ merge_item(perl);
+#endif
+
+ if (MpSrvINHERIT_SWITCHES(add)) {
+ /* only inherit base PerlSwitches if explicitly told to */
+ mrg->argv = base->argv;
+ }
+ else {
+ mrg->argv = add->argv;
+ }
+
+ mrg->flags = modperl_options_merge(p, base->flags, add->flags);
+
+ /* XXX: check if Perl*Handler is disabled */
+ for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) {
+ merge_handlers(MpSrvMERGE_HANDLERS, handlers_per_srv[i]);
+ }
+ for (i=0; i < MP_HANDLER_NUM_FILES; i++) {
+ merge_handlers(MpSrvMERGE_HANDLERS, handlers_files[i]);
+ }
+ for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) {
+ merge_handlers(MpSrvMERGE_HANDLERS, handlers_process[i]);
+ }
+ for (i=0; i < MP_HANDLER_NUM_PRE_CONNECTION; i++) {
+ merge_handlers(MpSrvMERGE_HANDLERS, handlers_pre_connection[i]);
+ }
+ for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) {
+ merge_handlers(MpSrvMERGE_HANDLERS, handlers_connection[i]);
+ }
+
+ if (modperl_is_running()) {
+ if (modperl_init_vhost(mrg->server, p, NULL) != OK) {
+ exit(1); /*XXX*/
+ }
+ }
+
+#ifdef USE_ITHREADS
+ merge_item(mip);
+#endif
+
+ return mrg;
+}
+
+/* any per-request cleanup goes here */
+
+apr_status_t modperl_config_request_cleanup(pTHX_ request_rec *r)
+{
+ apr_status_t retval;
+ MP_dRCFG;
+
+ retval = modperl_callback_per_dir(MP_CLEANUP_HANDLER, r, MP_HOOK_RUN_ALL);
+
+ /* undo changes to %ENV caused by +SetupEnv, perl-script, or
+ * $r->subprocess_env, so the values won't persist */
+ if (MpReqSETUP_ENV(rcfg)) {
+ modperl_env_request_unpopulate(aTHX_ r);
+ }
+
+ return retval;
+}
+
+apr_status_t modperl_config_req_cleanup(void *data)
+{
+ request_rec *r = (request_rec *)data;
+ apr_status_t rc;
+ MP_dINTERPa(r, NULL, NULL);
+
+ rc = modperl_config_request_cleanup(aTHX_ r);
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ return rc;
+}
+
+void *modperl_get_perl_module_config(ap_conf_vector_t *cv)
+{
+ return ap_get_module_config(cv, &perl_module);
+}
+
+void modperl_set_perl_module_config(ap_conf_vector_t *cv, void *cfg)
+{
+ ap_set_module_config(cv, &perl_module, cfg);
+}
+
+int modperl_config_apply_PerlModule(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p)
+{
+ char **entries;
+ int i;
+ dTHXa(perl);
+
+ entries = (char **)scfg->PerlModule->elts;
+ for (i = 0; i < scfg->PerlModule->nelts; i++){
+ if (modperl_require_module(aTHX_ entries[i], TRUE)){
+ MP_TRACE_d(MP_FUNC, "loaded Perl module %s for server %s",
+ entries[i], modperl_server_desc(s,p));
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Can't load Perl module %s for server %s, exiting...",
+ entries[i], modperl_server_desc(s,p));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+int modperl_config_apply_PerlRequire(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p)
+{
+ char **entries;
+ int i;
+ dTHXa(perl);
+
+ entries = (char **)scfg->PerlRequire->elts;
+ for (i = 0; i < scfg->PerlRequire->nelts; i++){
+ if (modperl_require_file(aTHX_ entries[i], TRUE)){
+ MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s",
+ entries[i], modperl_server_desc(s,p));
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Can't load Perl file: %s for server %s, exiting...",
+ entries[i], modperl_server_desc(s,p));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+int modperl_config_apply_PerlPostConfigRequire(server_rec *s,
+ modperl_config_srv_t *scfg,
+ apr_pool_t *p)
+{
+ modperl_require_file_t **requires;
+ int i;
+ MP_PERL_CONTEXT_DECLARE;
+
+ requires = (modperl_require_file_t **)scfg->PerlPostConfigRequire->elts;
+ for (i = 0; i < scfg->PerlPostConfigRequire->nelts; i++){
+ int retval;
+
+ MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl);
+ retval = modperl_require_file(aTHX_ requires[i]->file, TRUE);
+ modperl_env_sync_srv_env_hash2table(aTHX_ p, scfg);
+ modperl_env_sync_dir_env_hash2table(aTHX_ p, requires[i]->dcfg);
+ MP_PERL_CONTEXT_RESTORE;
+
+ if (retval) {
+ MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s",
+ requires[i]->file, modperl_server_desc(s, p));
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Can't load Perl file: %s for server %s, exiting...",
+ requires[i]->file, modperl_server_desc(s, p));
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+typedef struct {
+ AV *av;
+ I32 ix;
+ PerlInterpreter *perl;
+} svav_param_t;
+
+static
+#if AP_MODULE_MAGIC_AT_LEAST(20110329,0)
+apr_status_t
+#else
+void *
+#endif
+svav_getstr(void *buf, size_t bufsiz, void *param)
+{
+ svav_param_t *svav_param = (svav_param_t *)param;
+ dTHXa(svav_param->perl);
+ AV *av = svav_param->av;
+ SV *sv;
+ STRLEN n_a;
+
+ if (svav_param->ix > AvFILL(av)) {
+#if AP_MODULE_MAGIC_AT_LEAST(20110329,0)
+ return APR_EOF;
+#else
+ return NULL;
+#endif
+ }
+
+ sv = AvARRAY(av)[svav_param->ix++];
+ SvPV_force(sv, n_a);
+
+ apr_cpystrn(buf, SvPVX(sv), bufsiz);
+
+#if AP_MODULE_MAGIC_AT_LEAST(20110329,0)
+ return APR_SUCCESS;
+#else
+ return buf;
+#endif
+}
+
+const char *modperl_config_insert(pTHX_ server_rec *s,
+ apr_pool_t *p,
+ apr_pool_t *ptmp,
+ int override,
+ char *path,
+ int override_options,
+ ap_conf_vector_t *conf,
+ SV *lines)
+{
+ const char *errmsg;
+ cmd_parms parms;
+ svav_param_t svav_parms;
+ ap_directive_t *conftree = NULL;
+
+ memset(&parms, '\0', sizeof(parms));
+
+ parms.limited = -1;
+ parms.server = s;
+ parms.override = override;
+ parms.path = apr_pstrdup(p, path);
+ parms.pool = p;
+#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS
+ if (override_options == MP_HTTPD_OVERRIDE_OPTS_UNSET) {
+ parms.override_opts = MP_HTTPD_OVERRIDE_OPTS_DEFAULT;
+ }
+ else {
+ parms.override_opts = override_options;
+ }
+#endif
+
+ if (ptmp) {
+ parms.temp_pool = ptmp;
+ }
+ else {
+ apr_pool_create(&parms.temp_pool, p);
+ }
+
+ if (!(SvROK(lines) && (SvTYPE(SvRV(lines)) == SVt_PVAV))) {
+ return "not an array reference";
+ }
+
+ svav_parms.av = (AV*)SvRV(lines);
+ svav_parms.ix = 0;
+#ifdef USE_ITHREADS
+ svav_parms.perl = aTHX;
+#endif
+
+ parms.config_file = ap_pcfg_open_custom(p, "mod_perl",
+ &svav_parms, NULL,
+ svav_getstr, NULL);
+
+ errmsg = ap_build_config(&parms, p, parms.temp_pool, &conftree);
+
+ if (!errmsg) {
+ errmsg = ap_walk_config(conftree, &parms, conf);
+ }
+
+ ap_cfg_closefile(parms.config_file);
+
+ if (ptmp != parms.temp_pool) {
+ apr_pool_destroy(parms.temp_pool);
+ }
+
+ return errmsg;
+}
+
+const char *modperl_config_insert_parms(pTHX_ cmd_parms *parms,
+ SV *lines)
+{
+ return modperl_config_insert(aTHX_
+ parms->server,
+ parms->pool,
+ parms->temp_pool,
+ parms->override,
+ parms->path,
+#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS
+ parms->override_opts,
+#else
+ MP_HTTPD_OVERRIDE_OPTS_UNSET,
+#endif
+ parms->context,
+ lines);
+}
+
+
+const char *modperl_config_insert_server(pTHX_ server_rec *s, SV *lines)
+{
+ int override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
+ apr_pool_t *p = s->process->pconf;
+
+ return modperl_config_insert(aTHX_ s, p, NULL, override, NULL,
+ MP_HTTPD_OVERRIDE_OPTS_UNSET,
+ s->lookup_defaults, lines);
+}
+
+const char *modperl_config_insert_request(pTHX_
+ request_rec *r,
+ SV *lines,
+ int override,
+ char *path,
+ int override_options)
+{
+ const char *errmsg;
+ ap_conf_vector_t *dconf = ap_create_per_dir_config(r->pool);
+
+ if (!path) {
+ /* pass a non-NULL path if nothing else given and for compatibility */
+ path = "/";
+ }
+
+ errmsg = modperl_config_insert(aTHX_
+ r->server, r->pool, r->pool,
+ override, path, override_options,
+ dconf, lines);
+
+ if (errmsg) {
+ return errmsg;
+ }
+
+ r->per_dir_config =
+ ap_merge_per_dir_configs(r->pool,
+ r->per_dir_config,
+ dconf);
+
+ return NULL;
+}
+
+
+/* if r!=NULL check for dir PerlOptions, otherwise check for server
+ * PerlOptions, (s must be always set)
+ */
+int modperl_config_is_perl_option_enabled(pTHX_ request_rec *r,
+ server_rec *s, const char *name)
+{
+ U32 flag;
+
+ /* XXX: should we test whether perl is disabled for this server? */
+ /* if (!MpSrvENABLE(scfg)) { */
+ /* return 0; */
+ /* } */
+
+ if (r) {
+ if ((flag = modperl_flags_lookup_dir(name)) != -1) {
+ MP_dDCFG;
+ return MpDirFLAGS(dcfg) & flag ? 1 : 0;
+ }
+ else {
+ Perl_croak(aTHX_ "PerlOptions %s is not a directory option", name);
+ }
+ }
+ else {
+ if ((flag = modperl_flags_lookup_srv(name)) != -1) {
+ MP_dSCFG(s);
+ return MpSrvFLAGS(scfg) & flag ? 1 : 0;
+ }
+ else {
+ Perl_croak(aTHX_ "PerlOptions %s is not a server option", name);
+ }
+ }
+
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_config.h b/2_0_13/src/modules/perl/modperl_config.h
new file mode 100644
index 0000000..9139e20
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_config.h
@@ -0,0 +1,165 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_CONFIG_H
+#define MODPERL_CONFIG_H
+
+void *modperl_config_dir_create(apr_pool_t *p, char *dir);
+
+void *modperl_config_dir_merge(apr_pool_t *p, void *basev, void *addv);
+
+modperl_config_srv_t *modperl_config_srv_new(apr_pool_t *p, server_rec *s);
+
+modperl_config_dir_t *modperl_config_dir_new(apr_pool_t *p);
+
+modperl_config_req_t *modperl_config_req_new(request_rec *r);
+
+modperl_config_con_t *modperl_config_con_new(conn_rec *c);
+
+void *modperl_config_srv_create(apr_pool_t *p, server_rec *s);
+
+void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv);
+
+char **modperl_config_srv_argv_init(modperl_config_srv_t *scfg, int *argc);
+
+#define modperl_config_srv_argv_push(arg) \
+ *(const char **)apr_array_push(scfg->argv) = (arg)
+
+apr_status_t modperl_config_request_cleanup(pTHX_ request_rec *r);
+
+apr_status_t modperl_config_req_cleanup(void *data);
+
+/* use a subpool here to ensure that a PerlCleanupHandler is run before
+ * any other pool cleanup - suppools are destroyed first. Particularly a
+ * PerlCleanupHandler must run before request pnotes are dropped.
+ */
+#define modperl_config_req_cleanup_register(r, rcfg) \
+ if (r && !MpReqCLEANUP_REGISTERED(rcfg)) { \
+ apr_pool_t *p; \
+ apr_pool_create(&p, (r)->pool); \
+ apr_pool_cleanup_register(p, \
+ (void*)(r), \
+ modperl_config_req_cleanup, \
+ apr_pool_cleanup_null); \
+ MpReqCLEANUP_REGISTERED_On(rcfg); \
+ }
+
+void *modperl_get_perl_module_config(ap_conf_vector_t *cv);
+void modperl_set_perl_module_config(ap_conf_vector_t *cv, void *cfg);
+
+#if defined(MP_IN_XS) && defined(WIN32)
+# define modperl_get_module_config(v) \
+ modperl_get_perl_module_config((v))
+
+# define modperl_set_module_config(v, c) \
+ modperl_set_perl_module_config((v), (c))
+#else
+# define modperl_get_module_config(v) \
+ ap_get_module_config((v), &perl_module)
+
+# define modperl_set_module_config(v, c) \
+ ap_set_module_config((v), &perl_module, (c))
+#endif
+
+#define modperl_config_req_init(r, rcfg) \
+ if (!(rcfg)) { \
+ (rcfg) = modperl_config_req_new(r); \
+ modperl_set_module_config((r)->request_config, (rcfg)); \
+ }
+
+#define modperl_config_req_get(r) \
+ (r ? (modperl_config_req_t *) \
+ modperl_get_module_config((r)->request_config) : NULL)
+
+#define MP_dRCFG \
+ modperl_config_req_t *rcfg = modperl_config_req_get(r)
+
+#define modperl_config_con_init(c, ccfg) \
+ if (!ccfg) { \
+ ccfg = modperl_config_con_new(c); \
+ modperl_set_module_config((c)->conn_config, (ccfg)); \
+ }
+
+#define modperl_config_con_get(c) \
+ (c ? (modperl_config_con_t *) \
+ modperl_get_module_config((c)->conn_config) : NULL)
+
+#define MP_dCCFG \
+ modperl_config_con_t *ccfg = modperl_config_con_get(c)
+
+#define modperl_config_dir_get(r) \
+ (r ? (modperl_config_dir_t *) \
+ modperl_get_module_config((r)->per_dir_config) : NULL)
+
+#define modperl_config_dir_get_defaults(s) \
+ (modperl_config_dir_t *) \
+ modperl_get_module_config((s)->lookup_defaults)
+
+#define MP_dDCFG \
+ modperl_config_dir_t *dcfg = modperl_config_dir_get(r)
+
+#define modperl_config_srv_get(s) \
+ (modperl_config_srv_t *) \
+ modperl_get_module_config(s->module_config)
+
+#define MP_dSCFG(s) \
+ modperl_config_srv_t *scfg = modperl_config_srv_get(s)
+
+int modperl_config_apply_PerlModule(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p);
+
+int modperl_config_apply_PerlRequire(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p);
+
+int modperl_config_apply_PerlPostConfigRequire(server_rec *s,
+ modperl_config_srv_t *scfg,
+ apr_pool_t *p);
+
+const char *modperl_config_insert(pTHX_ server_rec *s,
+ apr_pool_t *p,
+ apr_pool_t *ptmp,
+ int override,
+ char *path,
+ int override_options,
+ ap_conf_vector_t *conf,
+ SV *lines);
+
+const char *modperl_config_insert_parms(pTHX_ cmd_parms *parms,
+ SV *lines);
+
+const char *modperl_config_insert_server(pTHX_ server_rec *s, SV *lines);
+
+const char *modperl_config_insert_request(pTHX_
+ request_rec *r,
+ SV *lines,
+ int override,
+ char *path,
+ int override_options);
+
+int modperl_config_is_perl_option_enabled(pTHX_ request_rec *r,
+ server_rec *s, const char *name);
+
+
+#endif /* MODPERL_CONFIG_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_const.c b/2_0_13/src/modules/perl/modperl_const.c
new file mode 100644
index 0000000..209226b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_const.c
@@ -0,0 +1,140 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+#include "modperl_const.h"
+
+typedef SV *(*constants_lookup)(pTHX_ const char *);
+typedef const char ** (*constants_group_lookup)(const char *);
+
+static void new_constsub(pTHX_ constants_lookup lookup,
+ HV *caller_stash, HV *stash,
+ const char *name)
+{
+ int name_len = strlen(name);
+ GV **gvp = (GV **)hv_fetch(stash, name, name_len, TRUE);
+
+ /* dont redefine */
+ if (!isGV(*gvp) || !GvCV(*gvp)) {
+ SV *val = (*lookup)(aTHX_ name);
+
+#if 0
+ Perl_warn(aTHX_ "newCONSTSUB(%s, %s, %s)\n",
+ HvNAME(stash), name, SvPV_nolen(val));
+#endif
+
+ newCONSTSUB(stash, (char *)name, val);
+#ifdef GvSHARED
+ GvSHARED_on(*gvp);
+#endif
+ }
+
+ /* export into callers namespace */
+ if (caller_stash) {
+ GV *alias = *(GV **)hv_fetch(caller_stash,
+ (char *)name, name_len, TRUE);
+
+ if (!isGV(alias)) {
+ gv_init(alias, caller_stash, name, name_len, TRUE);
+ }
+
+#ifdef MUTABLE_CV
+ GvCV_set(alias, MUTABLE_CV(SvREFCNT_inc(GvCV(*gvp))));
+#else
+ GvCV_set(alias, (CV*)(SvREFCNT_inc(GvCV(*gvp))));
+#endif
+ }
+}
+
+int modperl_const_compile(pTHX_ const char *classname,
+ const char *arg,
+ const char *name)
+{
+ HV *stash = gv_stashpv(classname, TRUE);
+ HV *caller_stash = (HV *)NULL;
+ constants_lookup lookup;
+ constants_group_lookup group_lookup;
+
+ if (strnEQ(classname, "APR", 3)) {
+ lookup = modperl_constants_lookup_apr_const;
+ group_lookup = modperl_constants_group_lookup_apr_const;
+ }
+ else if (strnEQ(classname, "Apache2", 7)) {
+ lookup = modperl_constants_lookup_apache2_const;
+ group_lookup = modperl_constants_group_lookup_apache2_const;
+ }
+ else {
+ lookup = modperl_constants_lookup_modperl;
+ group_lookup = modperl_constants_group_lookup_modperl;
+ }
+
+ if (*arg != '-') {
+ /* only export into callers namespace without -compile arg */
+ caller_stash = gv_stashpv(arg, TRUE);
+ }
+
+ if (*name == ':') {
+ int i;
+ const char **group;
+
+ name++;
+
+ group = (*group_lookup)(name);
+
+ for (i=0; group[i]; i++) {
+ new_constsub(aTHX_ lookup, caller_stash, stash, group[i]);
+ }
+ }
+ else {
+ if (*name == '&') {
+ name++;
+ }
+ new_constsub(aTHX_ lookup, caller_stash, stash, name);
+ }
+
+ return 1;
+}
+
+XS(XS_modperl_const_compile)
+{
+ I32 i;
+ STRLEN n_a;
+ char *stashname = HvNAME(GvSTASH(CvGV(cv)));
+ const char *classname, *arg;
+ dXSARGS;
+
+ if (items < 2) {
+ Perl_croak(aTHX_ "Usage: %s->compile(...)", stashname);
+ }
+
+ classname = *(stashname + 1) == 'P'
+ ? "APR::Const"
+ : (*stashname == 'A' ? "Apache2::Const" : "ModPerl");
+ arg = SvPV(ST(1),n_a);
+
+ for (i=2; i<items; i++) {
+ (void)modperl_const_compile(aTHX_ classname, arg, SvPV(ST(i), n_a));
+ }
+
+ XSRETURN_EMPTY;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_const.h b/2_0_13/src/modules/perl/modperl_const.h
new file mode 100644
index 0000000..f6ef50c
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_const.h
@@ -0,0 +1,40 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_CONST_H
+#define MODPERL_CONST_H
+
+#include "modperl_constants.h"
+
+int modperl_const_compile(pTHX_ const char *classname,
+ const char *arg,
+ const char *name);
+
+XS(XS_modperl_const_compile);
+
+#define MP_newModPerlConstXS(name) \
+ newXS(name "::Const::compile", \
+ CvXSUB(get_cv("ModPerl::Const::compile", TRUE)), \
+ __FILE__)
+
+#endif /* MODPERL_CONST_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_debug.c b/2_0_13/src/modules/perl/modperl_debug.c
new file mode 100644
index 0000000..8b880d9
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_debug.c
@@ -0,0 +1,84 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+char *modperl_server_desc(server_rec *s, apr_pool_t *p)
+{
+ return apr_psprintf(p, "%s:%u", s->server_hostname, s->port);
+}
+
+#ifdef MP_TRACE
+void modperl_apr_table_dump(pTHX_ apr_table_t *table, char *name)
+{
+ int i, tmp_len, len = 0;
+ char *fmt;
+ const apr_array_header_t *array = apr_table_elts(table);
+ apr_table_entry_t *elts = (apr_table_entry_t *)array->elts;
+
+ modperl_trace(MP_FUNC, "*** Contents of table '%s' ***", name);
+ for (i = 0; i < array->nelts; i++) {
+ if (elts[i].key && elts[i].val) {
+ tmp_len = strlen(elts[i].key);
+ if (tmp_len > len) {
+ len = tmp_len;
+ }
+ }
+ }
+ /* dump the table with keys aligned */
+ fmt = Perl_form(aTHX_ "%%-%ds => %%s", len);
+
+ for (i = 0; i < array->nelts; i++) {
+ if (!elts[i].key || !elts[i].val) {
+ continue;
+ }
+ modperl_trace(MP_FUNC, fmt, elts[i].key, elts[i].val);
+ }
+ modperl_trace(MP_FUNC, "");
+}
+#endif
+
+#ifdef MP_TRACE
+void modperl_perl_modglobal_dump(pTHX)
+{
+ HV *hv = PL_modglobal;
+ AV *val;
+ char *key;
+ I32 klen;
+ hv_iterinit(hv);
+
+ MP_TRACE_g(MP_FUNC, "|-------- PL_modglobal --------");
+#ifdef USE_ITHREADS
+ MP_TRACE_g(MP_FUNC, "| perl 0x%lx", (unsigned long)aTHX);
+#endif
+ MP_TRACE_g(MP_FUNC, "| PL_modglobal 0x%lx",
+ (unsigned long)PL_modglobal);
+
+ while ((val = (AV*)hv_iternextsv(hv, &key, &klen))) {
+ MP_TRACE_g(MP_FUNC, "| %s => 0x%lx", key, val);
+ }
+
+ MP_TRACE_g(MP_FUNC, "|-------- PL_modglobal --------");
+
+}
+#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_debug.h b/2_0_13/src/modules/perl/modperl_debug.h
new file mode 100644
index 0000000..da7fc4b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_debug.h
@@ -0,0 +1,49 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_DEBUG_H
+#define MODPERL_DEBUG_H
+
+#include "mod_perl.h"
+
+#ifdef MP_DEBUG
+# define MP_ASSERT(exp) ap_assert(exp)
+#else
+# define MP_ASSERT(exp) ((void)0)
+#endif
+
+#ifdef USE_ITHREADS
+# define MP_ASSERT_CONTEXT(perl) MP_ASSERT((perl) == PERL_GET_CONTEXT)
+#else
+# define MP_ASSERT_CONTEXT(perl) ((void)0)
+#endif
+
+char *modperl_server_desc(server_rec *s, apr_pool_t *p);
+
+#ifdef MP_TRACE
+void modperl_apr_table_dump(pTHX_ apr_table_t *table, char *name);
+/* dump the contents of PL_modglobal */
+void modperl_perl_modglobal_dump(pTHX);
+#endif
+
+#endif /* MODPERL_DEBUG_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_env.c b/2_0_13/src/modules/perl/modperl_env.c
new file mode 100644
index 0000000..62d4030
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_env.c
@@ -0,0 +1,727 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+#define EnvMgOK ((SV*)ENVHV && SvMAGIC((SV*)ENVHV))
+#define EnvMgObj (EnvMgOK ? SvMAGIC((SV*)ENVHV)->mg_ptr : NULL)
+#define EnvMgLen (EnvMgOK ? SvMAGIC((SV*)ENVHV)->mg_len : 0)
+#define EnvMgObjSet(val){ \
+ if (EnvMgOK) SvMAGIC((SV*)ENVHV)->mg_ptr = (char *)val;}
+#define EnvMgLenSet(val) {\
+ if (EnvMgOK) SvMAGIC((SV*)ENVHV)->mg_len = val;}
+
+/* XXX: move to utils? */
+static unsigned long modperl_interp_address(pTHX)
+{
+#ifdef USE_ITHREADS
+ return (unsigned long)aTHX;
+#else
+ return (unsigned long)0; /* just one interpreter */
+#endif
+}
+
+#define MP_ENV_HV_STORE(hv, key, val) STMT_START { \
+ I32 klen = strlen(key); \
+ SV **svp = hv_fetch(hv, key, klen, FALSE); \
+ SV *sv; \
+ \
+ if (svp) { \
+ sv_setpv(*svp, val); \
+ } \
+ else { \
+ sv = newSVpv(val, 0); \
+ (void)hv_store(hv, key, klen, sv, FALSE); \
+ modperl_envelem_tie(sv, key, klen); \
+ svp = &sv; \
+ } \
+ MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", key, val); \
+ \
+ SvTAINTED_on(*svp); \
+ } STMT_END
+
+void modperl_env_hv_store(pTHX_ const char *key, const char *val)
+{
+ MP_ENV_HV_STORE(ENVHV, key, val);
+}
+
+static MP_INLINE
+void modperl_env_hv_delete(pTHX_ HV *hv, char *key)
+{
+ I32 klen = strlen(key);
+ if (hv_exists(hv, key, klen)) {
+ (void)hv_delete(hv, key, strlen(key), G_DISCARD);
+ }
+}
+
+typedef struct {
+ const char *key;
+ I32 klen;
+ const char *val;
+ I32 vlen;
+ U32 hash;
+} modperl_env_ent_t;
+
+#define MP_ENV_ENT(k,v) \
+{ k, MP_SSTRLEN(k), v, MP_SSTRLEN(v), 0 }
+
+static modperl_env_ent_t MP_env_const_vars[] = {
+ MP_ENV_ENT("MOD_PERL", MP_VERSION_STRING),
+ MP_ENV_ENT("MOD_PERL_API_VERSION", MP_API_VERSION),
+ { NULL }
+};
+
+void modperl_env_hash_keys(pTHX)
+{
+ modperl_env_ent_t *ent = MP_env_const_vars;
+
+ while (ent->key) {
+ PERL_HASH(ent->hash, ent->key, ent->klen);
+ MP_TRACE_e(MP_FUNC, "[0x%lx] PERL_HASH: %s (len: %d)",
+ modperl_interp_address(aTHX), ent->key, ent->klen);
+ ent++;
+ }
+}
+
+void modperl_env_clear(pTHX)
+{
+ HV *hv = ENVHV;
+ U32 mg_flags;
+
+ modperl_env_untie(mg_flags);
+
+ MP_TRACE_e(MP_FUNC, "[0x%lx] %%ENV = ();", modperl_interp_address(aTHX));
+
+ hv_clear(hv);
+
+ modperl_env_tie(mg_flags);
+}
+
+#define MP_ENV_HV_STORE_TABLE_ENTRY(hv, elt) \
+ MP_ENV_HV_STORE(hv, elt.key, elt.val);
+
+static void modperl_env_table_populate(pTHX_ apr_table_t *table)
+{
+ HV *hv = ENVHV;
+ U32 mg_flags;
+ int i;
+ const apr_array_header_t *array;
+ apr_table_entry_t *elts;
+
+ modperl_env_init(aTHX);
+ modperl_env_untie(mg_flags);
+
+ array = apr_table_elts(table);
+ elts = (apr_table_entry_t *)array->elts;
+
+ for (i = 0; i < array->nelts; i++) {
+ if (!elts[i].key || !elts[i].val) {
+ continue;
+ }
+ MP_ENV_HV_STORE_TABLE_ENTRY(hv, elts[i]);
+ }
+
+ modperl_env_tie(mg_flags);
+}
+
+static void modperl_env_table_unpopulate(pTHX_ apr_table_t *table)
+{
+ HV *hv = ENVHV;
+ U32 mg_flags;
+ int i;
+ const apr_array_header_t *array;
+ apr_table_entry_t *elts;
+
+ modperl_env_untie(mg_flags);
+
+ array = apr_table_elts(table);
+ elts = (apr_table_entry_t *)array->elts;
+
+ for (i = 0; i < array->nelts; i++) {
+ if (!elts[i].key) {
+ continue;
+ }
+ modperl_env_hv_delete(aTHX_ hv, elts[i].key);
+ MP_TRACE_e(MP_FUNC, "delete $ENV{%s};", elts[i].key);
+ }
+
+ modperl_env_tie(mg_flags);
+}
+
+/* see the comment in modperl_env_sync_env_hash2table */
+static void modperl_env_sync_table(pTHX_ apr_table_t *table)
+{
+ int i;
+ const apr_array_header_t *array;
+ apr_table_entry_t *elts;
+ HV *hv = ENVHV;
+ SV **svp;
+
+ array = apr_table_elts(table);
+ elts = (apr_table_entry_t *)array->elts;
+
+ for (i = 0; i < array->nelts; i++) {
+ if (!elts[i].key) {
+ continue;
+ }
+ svp = hv_fetch(hv, elts[i].key, strlen(elts[i].key), FALSE);
+ if (svp) {
+ apr_table_set(table, elts[i].key, SvPV_nolen(*svp));
+ MP_TRACE_e(MP_FUNC, "(Set|Pass)Env '%s' '%s'", elts[i].key,
+ SvPV_nolen(*svp));
+ }
+ }
+ TAINT_NOT; /* SvPV_* causes the taint issue */
+}
+
+/* Make per-server PerlSetEnv and PerlPassEnv in sync with %ENV at
+ * config time (if perl is running), by copying %ENV values to the
+ * PerlSetEnv and PerlPassEnv tables (only for keys which are already
+ * in those tables)
+ */
+void modperl_env_sync_srv_env_hash2table(pTHX_ apr_pool_t *p,
+ modperl_config_srv_t *scfg)
+{
+ modperl_env_sync_table(aTHX_ scfg->SetEnv);
+ modperl_env_sync_table(aTHX_ scfg->PassEnv);
+}
+
+void modperl_env_sync_dir_env_hash2table(pTHX_ apr_pool_t *p,
+ modperl_config_dir_t *dcfg)
+{
+ modperl_env_sync_table(aTHX_ dcfg->SetEnv);
+}
+
+/* list of environment variables to pass by default */
+static const char *MP_env_pass_defaults[] = {
+ "PATH", "TZ", NULL
+};
+
+void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s)
+{
+ MP_dSCFG(s);
+ int i = 0;
+
+ /* make per-server PerlSetEnv and PerlPassEnv entries visible
+ * to %ENV at config time
+ */
+
+ for (i=0; MP_env_pass_defaults[i]; i++) {
+ const char *key = MP_env_pass_defaults[i];
+ char *val;
+
+ if (apr_table_get(scfg->SetEnv, key) ||
+ apr_table_get(scfg->PassEnv, key))
+ {
+ continue; /* already configured */
+ }
+
+ if ((val = getenv(key))) {
+ apr_table_set(scfg->PassEnv, key, val);
+ }
+ }
+
+ MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]"
+ "\n\t@ENV{keys scfg->SetEnv} = values scfg->SetEnv;",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(s, p));
+ modperl_env_table_populate(aTHX_ scfg->SetEnv);
+
+ MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]"
+ "\n\t@ENV{keys scfg->PassEnv} = values scfg->PassEnv;",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(s, p));
+ modperl_env_table_populate(aTHX_ scfg->PassEnv);
+}
+
+#define overlay_subprocess_env(r, tab) \
+ r->subprocess_env = apr_table_overlay(r->pool, \
+ r->subprocess_env, \
+ tab)
+
+void modperl_env_configure_request_dir(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+ MP_dDCFG;
+
+ /* populate %ENV and r->subprocess_env with per-directory
+ * PerlSetEnv entries.
+ *
+ * note that per-server PerlSetEnv entries, as well as
+ * PerlPassEnv entries (which are only per-server), are added
+ * to %ENV and r->subprocess_env via modperl_env_configure_request_srv
+ */
+
+ if (!apr_is_empty_table(dcfg->SetEnv)) {
+ apr_table_t *setenv_copy;
+
+ /* add per-directory PerlSetEnv entries to %ENV
+ * collisions with per-server PerlSetEnv entries are
+ * resolved via the nature of a Perl hash
+ */
+ MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]"
+ "\n\t@ENV{keys dcfg->SetEnv} = values dcfg->SetEnv;",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool));
+ modperl_env_table_populate(aTHX_ dcfg->SetEnv);
+
+ /* make sure the entries are in the subprocess_env table as well.
+ * we need to use apr_table_overlap (not apr_table_overlay) because
+ * r->subprocess_env might have per-server PerlSetEnv entries in it
+ * and using apr_table_overlay would generate duplicate entries.
+ * in order to use apr_table_overlap, though, we need to copy the
+ * the dcfg table so that pool requirements are satisfied */
+
+ setenv_copy = apr_table_copy(r->pool, dcfg->SetEnv);
+ apr_table_overlap(r->subprocess_env, setenv_copy, APR_OVERLAP_TABLES_SET);
+ }
+
+ MpReqPERL_SET_ENV_DIR_On(rcfg);
+}
+
+void modperl_env_configure_request_srv(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+ MP_dSCFG(r->server);
+
+ /* populate %ENV and r->subprocess_env with per-server PerlSetEnv
+ * and PerlPassEnv entries.
+ *
+ * although both are setup in %ENV in modperl_request_configure_server
+ * %ENV will be reset via modperl_env_request_unpopulate.
+ */
+
+ if (!apr_is_empty_table(scfg->SetEnv)) {
+ MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]"
+ "\n\t@ENV{keys scfg->SetEnv} = values scfg->SetEnv;",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool));
+ modperl_env_table_populate(aTHX_ scfg->SetEnv);
+
+ overlay_subprocess_env(r, scfg->SetEnv);
+ }
+
+ if (!apr_is_empty_table(scfg->PassEnv)) {
+ MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]"
+ "\n\t@ENV{keys scfg->PassEnv} = values scfg->PassEnv;",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool));
+ modperl_env_table_populate(aTHX_ scfg->PassEnv);
+
+ overlay_subprocess_env(r, scfg->PassEnv);
+ }
+
+ MpReqPERL_SET_ENV_SRV_On(rcfg);
+}
+
+void modperl_env_default_populate(pTHX)
+{
+ modperl_env_ent_t *ent = MP_env_const_vars;
+ HV *hv = ENVHV;
+ U32 mg_flags;
+
+ modperl_env_untie(mg_flags);
+
+ while (ent->key) {
+ SV *sv = newSVpvn(ent->val, ent->vlen);
+ (void)hv_store(hv, ent->key, ent->klen,
+ sv, ent->hash);
+ MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", ent->key, ent->val);
+ modperl_envelem_tie(sv, ent->key, ent->klen);
+ ent++;
+ }
+
+ modperl_env_tie(mg_flags);
+}
+
+void modperl_env_request_populate(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+
+ /* this is called under the following conditions
+ * - if PerlOptions +SetupEnv
+ * - if $r->subprocess_env() is called in a void context with no args
+ *
+ * normally, %ENV is only populated once per request (if at all) -
+ * just prior to content generation if +SetupEnv.
+ *
+ * however, in the $r->subprocess_env() case it will be called
+ * more than once - once for each void call, and once again just
+ * prior to content generation. while costly, the multiple
+ * passes are required, otherwise void calls would prohibit later
+ * phases from populating %ENV with new subprocess_env table entries
+ */
+
+ MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s%s]"
+ "\n\t@ENV{keys r->subprocess_env} = values r->subprocess_env;",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool), r->uri);
+
+ /* we can eliminate some of the cost by only doing CGI variables once
+ * per-request no matter how many times $r->subprocess_env() is called
+ */
+ if (! MpReqSETUP_ENV(rcfg)) {
+
+ ap_add_common_vars(r);
+ ap_add_cgi_vars(r);
+
+ }
+
+ modperl_env_table_populate(aTHX_ r->subprocess_env);
+
+ /* don't set up CGI variables again this request.
+ * this also triggers modperl_env_request_unpopulate, which
+ * resets %ENV between requests - see modperl_config_request_cleanup
+ */
+ MpReqSETUP_ENV_On(rcfg);
+}
+
+void modperl_env_request_unpopulate(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+
+ /* unset only once */
+ if (!MpReqSETUP_ENV(rcfg)) {
+ return;
+ }
+
+ MP_TRACE_e(MP_FUNC,
+ "\n\t[0x%lx/%s%s]\n\tdelete @ENV{keys r->subprocess_env};",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool), r->uri);
+ modperl_env_table_unpopulate(aTHX_ r->subprocess_env);
+
+ MpReqSETUP_ENV_Off(rcfg);
+}
+
+void modperl_env_request_tie(pTHX_ request_rec *r)
+{
+ EnvMgObjSet(r);
+ EnvMgLenSet(-1);
+
+#ifdef MP_PERL_HV_GMAGICAL_AWARE
+ MP_TRACE_e(MP_FUNC, "[0x%lx] tie %%ENV, $r\t (%s%s)",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool), r->uri);
+ SvGMAGICAL_on((SV*)ENVHV);
+#endif
+}
+
+void modperl_env_request_untie(pTHX_ request_rec *r)
+{
+ EnvMgObjSet(NULL);
+
+#ifdef MP_PERL_HV_GMAGICAL_AWARE
+ MP_TRACE_e(MP_FUNC, "[0x%lx] untie %%ENV; # from r\t (%s%s)",
+ modperl_interp_address(aTHX),
+ modperl_server_desc(r->server, r->pool), r->uri);
+ SvGMAGICAL_off((SV*)ENVHV);
+#endif
+}
+
+/* handy access to perl's original virtual tables
+ */
+#define MP_PL_vtbl_call(name, meth) \
+ PL_vtbl_##name.svt_##meth(aTHX_ sv, mg)
+
+#define MP_dENV_KEY \
+ STRLEN klen; \
+ const char *key = (const char *)MgPV(mg,klen)
+
+#define MP_dENV_VAL \
+ STRLEN vlen; \
+ const char *val = (const char *)SvPV(sv,vlen)
+
+/*
+ * XXX: what we do here might change:
+ * - make it optional for %ENV to be tied to r->subprocess_env
+ * - make it possible to modify environ
+ * - we could allow modification of environ if mpm isn't threaded
+ * - we could allow modification of environ if variable isn't a CGI
+ * variable (still could cause problems)
+ */
+/*
+ * problems we are trying to solve:
+ * - environ is shared between threads
+ * + Perl does not serialize access to environ
+ * + even if it did, CGI variables cannot be shared between threads!
+ * problems we create by trying to solve above problems:
+ * - a forked process will not inherit the current %ENV
+ * - C libraries might rely on environ, e.g. DBD::Oracle
+ */
+static int modperl_env_magic_set_all(pTHX_ SV *sv, MAGIC *mg)
+{
+ request_rec *r = (request_rec *)EnvMgObj;
+
+ if (r) {
+ if (PL_localizing) {
+ /* local %ENV = (FOO => 'bar', BIZ => 'baz') */
+ HE *entry;
+ STRLEN n_a;
+
+ hv_iterinit((HV*)sv);
+ while ((entry = hv_iternext((HV*)sv))) {
+ I32 keylen;
+ apr_table_set(r->subprocess_env,
+ hv_iterkey(entry, &keylen),
+ SvPV(hv_iterval((HV*)sv, entry), n_a));
+ MP_TRACE_e(MP_FUNC, "[0x%lx] localizing: %s => %s",
+ modperl_interp_address(aTHX),
+ hv_iterkey(entry, &keylen),
+ SvPV(hv_iterval((HV*)sv, entry), n_a));
+ }
+ }
+ }
+ else {
+#ifdef MP_TRACE
+ HE *entry;
+ STRLEN n_a;
+
+ MP_TRACE_e(MP_FUNC, "\n\t[0x%lx] populating %%ENV:",
+ modperl_interp_address(aTHX));
+
+ hv_iterinit((HV*)sv);
+
+ while ((entry = hv_iternext((HV*)sv))) {
+ I32 keylen;
+ MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";",
+ hv_iterkey(entry, &keylen),
+ SvPV(hv_iterval((HV*)sv, entry), n_a));
+ }
+#endif
+ return MP_PL_vtbl_call(env, set);
+ }
+
+ return 0;
+}
+
+static int modperl_env_magic_clear_all(pTHX_ SV *sv, MAGIC *mg)
+{
+ request_rec *r = (request_rec *)EnvMgObj;
+
+ if (r) {
+ apr_table_clear(r->subprocess_env);
+ MP_TRACE_e(MP_FUNC, "[0x%lx] clearing all magic off r->subprocess_env",
+ modperl_interp_address(aTHX));
+ }
+ else {
+ MP_TRACE_e(MP_FUNC, "[0x%lx] %%ENV = ();",
+ modperl_interp_address(aTHX));
+ return MP_PL_vtbl_call(env, clear);
+ }
+
+ return 0;
+}
+
+static int modperl_env_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *name, I32 namlen)
+{
+ MP_TRACE_e(MP_FUNC, "setting up %%ENV element magic");
+ sv_magicext(nsv, mg->mg_obj, toLOWER(mg->mg_type), &MP_vtbl_envelem, name, namlen);
+
+ return 1;
+}
+
+static int modperl_env_magic_local_all(pTHX_ SV *nsv, MAGIC *mg)
+{
+ MAGIC *nmg;
+ MP_TRACE_e(MP_FUNC, "localizing %%ENV");
+ nmg = sv_magicext(nsv, mg->mg_obj, mg->mg_type, &MP_vtbl_env, (char*)NULL, 0);
+ nmg->mg_ptr = mg->mg_ptr;
+ nmg->mg_flags |= MGf_COPY;
+#if (PERL_REVISION == 5 && PERL_VERSION == 8 && PERL_SUBVERSION > 8) || \
+ MP_PERL_VERSION_AT_LEAST(5, 9, 3)
+ nmg->mg_flags |= MGf_LOCAL;
+#endif
+
+ return 1;
+}
+
+static int modperl_env_magic_set(pTHX_ SV *sv, MAGIC *mg)
+{
+ request_rec *r = (request_rec *)EnvMgObj;
+
+ if (r) {
+ MP_dENV_KEY;
+ MP_dENV_VAL;
+ apr_table_set(r->subprocess_env, key, val);
+ MP_TRACE_e(MP_FUNC, "[0x%lx] r->subprocess_env set: %s => %s",
+ modperl_interp_address(aTHX), key, val);
+ }
+ else {
+#ifdef MP_TRACE
+ MP_dENV_KEY;
+ MP_dENV_VAL;
+ MP_TRACE_e(MP_FUNC,
+ "[0x%lx] $ENV{%s} = \"%s\";",
+ modperl_interp_address(aTHX), key, val);
+#endif
+ return MP_PL_vtbl_call(envelem, set);
+ }
+
+ return 0;
+}
+
+static int modperl_env_magic_clear(pTHX_ SV *sv, MAGIC *mg)
+{
+ request_rec *r = (request_rec *)EnvMgObj;
+
+ if (r) {
+ MP_dENV_KEY;
+ apr_table_unset(r->subprocess_env, key);
+ MP_TRACE_e(MP_FUNC, "[0x%lx] r->subprocess_env unset: %s",
+ modperl_interp_address(aTHX), key);
+ }
+ else {
+#ifdef MP_TRACE
+ MP_dENV_KEY;
+ MP_TRACE_e(MP_FUNC, "[0x%lx] delete $ENV{%s};",
+ modperl_interp_address(aTHX), key);
+#endif
+ return MP_PL_vtbl_call(envelem, clear);
+ }
+
+ return 0;
+}
+
+#ifdef MP_PERL_HV_GMAGICAL_AWARE
+static int modperl_env_magic_get(pTHX_ SV *sv, MAGIC *mg)
+{
+ request_rec *r = (request_rec *)EnvMgObj;
+
+ if (r) {
+ MP_dENV_KEY;
+ const char *val;
+
+ if ((val = apr_table_get(r->subprocess_env, key))) {
+ sv_setpv(sv, val);
+ MP_TRACE_e(MP_FUNC,
+ "[0x%lx] r->subprocess_env get: %s => %s",
+ modperl_interp_address(aTHX), key, val);
+ }
+ else {
+ sv_setsv(sv, &PL_sv_undef);
+ MP_TRACE_e(MP_FUNC,
+ "[0x%lx] r->subprocess_env get: %s => undef",
+ modperl_interp_address(aTHX), key);
+ }
+ }
+ else {
+ /* there is no svt_get in PL_vtbl_envelem */
+#ifdef MP_TRACE
+ MP_dENV_KEY;
+ MP_TRACE_e(MP_FUNC,
+ "[0x%lx] there is no svt_get in PL_vtbl_envelem: %s",
+ modperl_interp_address(aTHX), key);
+#endif
+ }
+
+ return 0;
+}
+#endif
+
+/* override %ENV virtual tables with our own */
+MGVTBL MP_vtbl_env = {
+ 0,
+ modperl_env_magic_set_all,
+ 0,
+ modperl_env_magic_clear_all,
+ 0,
+ modperl_env_magic_copy,
+ 0,
+ modperl_env_magic_local_all
+};
+
+MGVTBL MP_vtbl_envelem = {
+ 0,
+ modperl_env_magic_set,
+ 0,
+ modperl_env_magic_clear,
+ 0
+};
+
+void modperl_env_init(pTHX)
+{
+ MAGIC *mg;
+
+ /* Find the 'E' magic on %ENV */
+ if (!PL_envgv)
+ return;
+ if (!SvRMAGICAL(ENVHV))
+ return;
+ mg = mg_find((const SV *)ENVHV, PERL_MAGIC_env);
+ if (!mg)
+ return;
+
+ /* Ignore it if it isn't perl's original version */
+ if (mg->mg_virtual != &PL_vtbl_env)
+ return;
+
+ MP_TRACE_e(MP_FUNC, "env_init - ptr: %x obj: %x flags: %x",
+ mg->mg_ptr, mg->mg_obj, mg->mg_flags);
+
+ /* Remove it */
+#if MP_PERL_VERSION_AT_LEAST(5, 13, 6)
+ mg_free_type((SV*)ENVHV, PERL_MAGIC_env);
+#else
+ mg_free((SV*)ENVHV);
+#endif
+
+ /* Add our version instead */
+ mg = sv_magicext((SV*)ENVHV, (SV*)NULL, PERL_MAGIC_env, &MP_vtbl_env, (char*)NULL, 0);
+ mg->mg_flags |= MGf_COPY;
+#if (PERL_REVISION == 5 && PERL_VERSION == 8 && PERL_SUBVERSION > 8) || \
+ MP_PERL_VERSION_AT_LEAST(5, 9, 3)
+ mg->mg_flags |= MGf_LOCAL;
+#endif
+}
+
+void modperl_env_unload(pTHX)
+{
+ MAGIC *mg;
+
+ /* Find the 'E' magic on %ENV */
+ if (!PL_envgv)
+ return;
+ if (!SvRMAGICAL(ENVHV))
+ return;
+ mg = mg_find((const SV *)ENVHV, PERL_MAGIC_env);
+ if (!mg)
+ return;
+
+ /* Ignore it if it isn't our version */
+ if (mg->mg_virtual != &MP_vtbl_env)
+ return;
+
+ MP_TRACE_e(MP_FUNC, "env_unload - ptr: %x obj: %x flags: %x",
+ mg->mg_ptr, mg->mg_obj, mg->mg_flags);
+
+ /* Remove it */
+#if MP_PERL_VERSION_AT_LEAST(5, 13, 6)
+ mg_free_type((SV*)ENVHV, PERL_MAGIC_env);
+#else
+ mg_free((SV*)ENVHV);
+#endif
+
+ /* Restore perl's original version */
+ sv_magicext((SV*)ENVHV, (SV*)NULL, PERL_MAGIC_env, &PL_vtbl_env, (char*)NULL, 0);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_env.h b/2_0_13/src/modules/perl/modperl_env.h
new file mode 100644
index 0000000..3f8f60b
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_env.h
@@ -0,0 +1,75 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_ENV_H
+#define MODPERL_ENV_H
+
+#ifndef ENVHV
+# define ENVHV GvHV(PL_envgv)
+#endif
+
+#define modperl_env_untie(mg_flags) \
+ MP_magical_untie(ENVHV, mg_flags)
+
+#define modperl_env_tie(mg_flags) \
+ MP_magical_tie(ENVHV, mg_flags)
+
+#define modperl_envelem_tie(sv, key, klen) \
+ sv_magicext(sv, (SV *)NULL, PERL_MAGIC_envelem, &MP_vtbl_envelem, key, klen)
+
+void modperl_env_hash_keys(pTHX);
+
+void modperl_env_clear(pTHX);
+
+void modperl_env_hv_store(pTHX_ const char *key, const char *val);
+
+void modperl_env_sync_srv_env_hash2table(pTHX_ apr_pool_t *p,
+ modperl_config_srv_t *scfg);
+
+void modperl_env_sync_dir_env_hash2table(pTHX_ apr_pool_t *p,
+ modperl_config_dir_t *dcfg);
+
+void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s);
+
+void modperl_env_configure_request_srv(pTHX_ request_rec *r);
+
+void modperl_env_configure_request_dir(pTHX_ request_rec *r);
+
+void modperl_env_default_populate(pTHX);
+
+void modperl_env_request_populate(pTHX_ request_rec *r);
+
+void modperl_env_request_unpopulate(pTHX_ request_rec *r);
+
+void modperl_env_request_tie(pTHX_ request_rec *r);
+
+void modperl_env_request_untie(pTHX_ request_rec *r);
+
+void modperl_env_init(pTHX);
+
+void modperl_env_unload(pTHX);
+
+extern MGVTBL MP_vtbl_env;
+extern MGVTBL MP_vtbl_envelem;
+
+#endif /* MODPERL_ENV_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_error.c b/2_0_13/src/modules/perl/modperl_error.c
new file mode 100644
index 0000000..2f83216
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_error.c
@@ -0,0 +1,102 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+static const char *MP_error_strings[] = {
+ "exit was called", /* MODPERL_RC_EXIT */
+ "filter handler has failed", /* MODPERL_FILTER_ERROR */
+};
+
+#define MP_error_strings_size \
+ sizeof(MP_error_strings) / sizeof(MP_error_strings[0])
+
+char *modperl_error_strerror(pTHX_ apr_status_t rc)
+{
+ char *ptr;
+ char buf[256];
+
+ if (rc >= APR_OS_START_USERERR &&
+ rc < APR_OS_START_USERERR + MP_error_strings_size) {
+ /* custom mod_perl errors */
+ ptr = (char*)MP_error_strings[(int)(rc - APR_OS_START_USERERR)];
+ }
+ else {
+ /* apache apr errors */
+ ptr = apr_strerror(rc, buf, sizeof(buf));
+ }
+
+ /* must copy the string and not return a pointer to the local
+ * address. Using a single (per interpreter) static buffer.
+ */
+ return Perl_form(aTHX_ "%s", ptr ? ptr : "unknown error");
+}
+
+
+/* modperl_croak notes: under -T we can't really do anything when die
+ * was called in the stacked eval_sv (which is the case when a
+ * response handler calls a filter handler and that filter calls die
+ * ""). for example trying to require a file in modperl_croak(), will
+ * cause 'panic: POPSTACK' and the process will exit. Dave fixed that
+ * in perl Change 23209 by davem@davem-percy on 2004/08/09 19:48:57,
+ * which will hopefully appear in perl 5.8.6. for now workaround this
+ * perl bug by setting the taint mode off for the APR/Error loading.
+ */
+
+/* croak with $@ as a APR::Error object
+ * rc - set to apr_status_t value
+ * file - set to the callers filename
+ * line - set to the callers line number
+ * func - set to the function name
+ */
+void modperl_croak(pTHX_ apr_status_t rc, const char* func)
+{
+ HV *stash;
+ HV *data;
+ int is_tainted = PL_tainted;
+
+ /* see the explanation above */
+ if (is_tainted) {
+ TAINT_NOT;
+ }
+ Perl_require_pv(aTHX_ "APR/Error.pm");
+ if (is_tainted) {
+ TAINT;
+ }
+
+ if (SvTRUE(ERRSV)) {
+ Perl_croak(aTHX_ (char *)NULL);
+ }
+
+ stash = gv_stashpvn("APR::Error", 10, FALSE);
+ data = newHV();
+ /* $@ = bless {}, "APR::Error"; */
+ sv_setsv(ERRSV, sv_bless(newRV_noinc((SV*)data), stash));
+
+ sv_setiv(*hv_fetch(data, "rc", 2, 1), rc);
+ sv_setpv(*hv_fetch(data, "file", 4, 1), CopFILE(PL_curcop));
+ sv_setiv(*hv_fetch(data, "line", 4, 1), CopLINE(PL_curcop));
+ sv_setpv(*hv_fetch(data, "func", 4, 1), func);
+
+ Perl_croak(aTHX_ (char *)NULL);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_error.h b/2_0_13/src/modules/perl/modperl_error.h
new file mode 100644
index 0000000..0a4d82c
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_error.h
@@ -0,0 +1,115 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_ERROR_H
+#define MODPERL_ERROR_H
+
+/*** mod_perl custom errors come here ***/
+
+/* to check whether $@ is set by ModPerl::Util::exit */
+#define MODPERL_RC_EXIT APR_OS_START_USERERR + 0
+/* indicate the filter error problem */
+#define MODPERL_FILTER_ERROR APR_OS_START_USERERR + 1
+
+/**
+ * return the string representation of the error code
+ * @param rc error code
+ * @return the error string
+ *
+ * The return value must be immediately copied unless used only in a
+ * limited visible scope where it's clear that Perl_form() is not
+ * called again (which could happen indirectly). If unsure, copy.
+ */
+char *modperl_error_strerror(pTHX_ apr_status_t rc);
+
+void modperl_croak(pTHX_ apr_status_t rc, const char* func);
+
+#ifdef USE_ITHREADS
+#define MP_PUTBACK_IF_USED() STMT_START \
+ { \
+ modperl_interp_t *interp = modperl_thx_interp_get(aTHX); \
+ if (interp && interp->refcnt > 1) { \
+ modperl_interp_unselect(interp); \
+ } \
+ } STMT_END
+#else
+#define MP_PUTBACK_IF_USED() NOOP
+#endif
+
+#define MP_CROAK_PUTBACK(rc, func) STMT_START \
+ { \
+ MP_PUTBACK_IF_USED(); \
+ modperl_croak(aTHX_ rc, func); \
+ } STMT_END
+
+#define MP_RUN_CROAK(rc_run, func) STMT_START \
+ { \
+ apr_status_t rc = rc_run; \
+ if (rc != APR_SUCCESS) { \
+ modperl_croak(aTHX_ rc, func); \
+ } \
+ } STMT_END
+
+#define MP_RUN_CROAK_PUTBACK(rc_run, func) STMT_START \
+ { \
+ apr_status_t rc = rc_run; \
+ if (rc != APR_SUCCESS) { \
+ MP_PUTBACK_IF_USED(); \
+ modperl_croak(aTHX_ rc, func); \
+ } \
+ } STMT_END
+
+#define MP_RUN_CROAK_RESET_OK(s, rc_run, func) STMT_START \
+ { \
+ apr_status_t rc = rc_run; \
+ if (rc != APR_SUCCESS) { \
+ if (APR_STATUS_IS_ECONNRESET(rc) || \
+ APR_STATUS_IS_ECONNABORTED(rc)) { \
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, \
+ "%s got: %s", func, \
+ modperl_error_strerror(aTHX_ rc)); \
+ } \
+ else { \
+ modperl_croak(aTHX_ rc, func); \
+ } \
+ } \
+ } STMT_END
+
+#define MP_RUN_CROAK_RESET_OK_PUTBACK(s, rc_run, func) STMT_START \
+ { \
+ apr_status_t rc = rc_run; \
+ if (rc != APR_SUCCESS) { \
+ if (APR_STATUS_IS_ECONNRESET(rc) || \
+ APR_STATUS_IS_ECONNABORTED(rc)) { \
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, \
+ "%s got: %s", func, \
+ modperl_error_strerror(aTHX_ rc)); \
+ } \
+ else { \
+ MP_PUTBACK_IF_USED(); \
+ modperl_croak(aTHX_ rc, func); \
+ } \
+ } \
+ } STMT_END
+
+#endif /* MODPERL_ERROR_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_filter.c b/2_0_13/src/modules/perl/modperl_filter.c
new file mode 100644
index 0000000..76be3e0
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_filter.c
@@ -0,0 +1,1301 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* helper funcs */
+
+#define MP_FILTER_NAME_FORMAT " %s\n\n\t"
+
+#define MP_FILTER_NAME(f) \
+ (is_modperl_filter(f) \
+ ? modperl_handler_name( \
+ ((modperl_filter_ctx_t *)(f)->ctx)->handler) \
+ : (f)->frec->name)
+
+#define MP_FILTER_TYPE(filter) \
+ (is_modperl_filter(filter->f) \
+ ? ((modperl_filter_ctx_t *)(filter)->f->ctx)->handler->attrs & \
+ MP_FILTER_CONNECTION_HANDLER ? "connection" : "request" \
+ : "unknown")
+
+#define MP_FILTER_MODE(filter) \
+ (filter->mode == MP_INPUT_FILTER_MODE ? "input" : "output")
+
+#define MP_FILTER_POOL(f) f->r ? f->r->pool : f->c->pool
+
+/* allocate wbucket memory using a sub-pool and not a ap_filter_t
+ * pool, since we may need many of these if the filter is invoked
+ * multiple times */
+#define WBUCKET_INIT(filter) \
+ if (!filter->wbucket) { \
+ modperl_wbucket_t *wb = \
+ (modperl_wbucket_t *)apr_pcalloc(filter->temp_pool, \
+ sizeof(*wb)); \
+ wb->pool = filter->pool; \
+ wb->filters = &(filter->f->next); \
+ wb->outcnt = 0; \
+ wb->r = NULL; \
+ wb->header_parse = 0; \
+ filter->wbucket = wb; \
+ }
+
+#define FILTER_FREE(filter) \
+ apr_pool_destroy(filter->temp_pool);
+
+/* Save the value of $@ if it was set */
+#define MP_FILTER_SAVE_ERRSV(tmpsv) \
+ if (SvTRUE(ERRSV)) { \
+ tmpsv = newSVsv(ERRSV); \
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT \
+ "Saving $@='%s'", \
+ MP_FILTER_NAME(filter->f), \
+ SvPVX(tmpsv) \
+ ); \
+ }
+
+/* Restore previously saved value of $@. if there was a filter error
+ * it'd have been logged by modperl_errsv call following
+ * modperl_callback */
+#define MP_FILTER_RESTORE_ERRSV(tmpsv) \
+ if (tmpsv) { \
+ sv_setsv(ERRSV, tmpsv); \
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT \
+ "Restoring $@='%s'", \
+ MP_FILTER_NAME(filter->f), \
+ SvPVX(tmpsv) \
+ ); \
+ }
+
+/* this function is for tracing only, it's not optimized for performance */
+static int is_modperl_filter(ap_filter_t *f)
+{
+ const char *name = f->frec->name;
+
+ /* frec->name is always lowercased */
+ if (!strcasecmp(name, MP_FILTER_CONNECTION_INPUT_NAME) ||
+ !strcasecmp(name, MP_FILTER_CONNECTION_OUTPUT_NAME) ||
+ !strcasecmp(name, MP_FILTER_REQUEST_INPUT_NAME) ||
+ !strcasecmp(name, MP_FILTER_REQUEST_OUTPUT_NAME) ) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+MP_INLINE static apr_status_t send_input_eos(modperl_filter_t *filter)
+{
+ apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc;
+ apr_bucket *b = apr_bucket_eos_create(ba);
+ APR_BRIGADE_INSERT_TAIL(filter->bb_out, b);
+ ((modperl_filter_ctx_t *)filter->f->ctx)->sent_eos = 1;
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "write out: EOS bucket", MP_FILTER_NAME(filter->f));
+ return APR_SUCCESS;
+}
+
+MP_INLINE static apr_status_t send_input_flush(modperl_filter_t *filter)
+{
+ apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc;
+ apr_bucket *b = apr_bucket_flush_create(ba);
+ APR_BRIGADE_INSERT_TAIL(filter->bb_out, b);
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "write out: FLUSH bucket", MP_FILTER_NAME(filter->f));
+ return APR_SUCCESS;
+}
+
+MP_INLINE static apr_status_t send_output_eos(ap_filter_t *f)
+{
+ apr_bucket_alloc_t *ba = f->c->bucket_alloc;
+ apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f),
+ ba);
+ apr_bucket *b = apr_bucket_eos_create(ba);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+ ((modperl_filter_ctx_t *)f->ctx)->sent_eos = 1;
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "write out: EOS bucket in separate bb", MP_FILTER_NAME(f));
+ return ap_pass_brigade(f->next, bb);
+}
+
+MP_INLINE static apr_status_t send_output_flush(ap_filter_t *f)
+{
+ apr_bucket_alloc_t *ba = f->c->bucket_alloc;
+ apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f),
+ ba);
+ apr_bucket *b = apr_bucket_flush_create(ba);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "write out: FLUSH bucket in separate bb", MP_FILTER_NAME(f));
+ return ap_pass_brigade(f, bb);
+}
+
+/* simple buffer api */
+
+MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *wb,
+ const char *buf, apr_size_t len,
+ int add_flush_bucket)
+{
+ apr_bucket_alloc_t *ba = (*wb->filters)->c->bucket_alloc;
+ apr_bucket_brigade *bb;
+ apr_bucket *bucket;
+
+ /* reset the counter to 0 as early as possible and in one place,
+ * since this function will always either pass the data out (and
+ * it has 'len' already) or return an error.
+ */
+ wb->outcnt = 0;
+
+ if (wb->header_parse) {
+ request_rec *r = wb->r;
+ const char *body;
+ int status;
+
+ MP_TRACE_f(MP_FUNC, "parsing headers: %db [%s]", len,
+ MP_TRACE_STR_TRUNC(wb->pool, buf, len));
+
+ status = modperl_cgi_header_parse(r, (char *)buf, &len, &body);
+
+ wb->header_parse = 0; /* only once per-request */
+
+ if (status == HTTP_MOVED_TEMPORARILY) {
+ return APR_SUCCESS; /* XXX: HTTP_MOVED_TEMPORARILY ? */
+ }
+ else if (status != OK) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING,
+ 0, r->server, "%s did not send an HTTP header",
+ r->uri);
+ r->status = status;
+ /* XXX: body == NULL here */
+ return APR_SUCCESS;
+ }
+ else if (!len) {
+ return APR_SUCCESS;
+ }
+
+ buf = body;
+ }
+
+ /* this is a note for filter writers who may decide that there is
+ * a bug in mod_perl. We send a transient bucket. That means that
+ * this bucket can't be stored inside a filter without copying the
+ * data in it. This is done automatically by apr_bucket_setaside,
+ * which is written exactly for the purpose to make setaside
+ * operation transparent to the kind of bucket.
+ */
+ bucket = apr_bucket_transient_create(buf, len, ba);
+ bb = apr_brigade_create(wb->pool, ba);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+
+ if (add_flush_bucket) {
+ /* append the flush bucket rather then calling ap_rflush, to
+ * prevent a creation of yet another bb, which will cause an
+ * extra call for each filter in the chain */
+ apr_bucket *bucket = apr_bucket_flush_create(ba);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ }
+
+ MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %db [%s]"
+ "\t\tfrom %s\n\t\tto %s filter handler",
+ len,
+ MP_TRACE_STR_TRUNC(wb->pool, buf, len),
+ ((wb->r && wb->filters == &wb->r->output_filters)
+ ? "response handler" : "current filter handler"),
+ MP_FILTER_NAME(*(wb->filters)));
+
+ return ap_pass_brigade(*(wb->filters), bb);
+}
+
+/* flush data if any,
+ * if add_flush_bucket is TRUE
+ * if there is data to flush
+ * a flush bucket is added to the tail of bb with data
+ * else
+ * a flush bucket is sent in its own bb
+ * else
+ * nothing is sent
+ */
+MP_INLINE apr_status_t modperl_wbucket_flush(modperl_wbucket_t *wb,
+ int add_flush_bucket)
+{
+ apr_status_t rv = APR_SUCCESS;
+
+ if (wb->outcnt) {
+ rv = modperl_wbucket_pass(wb, wb->outbuf, wb->outcnt,
+ add_flush_bucket);
+ }
+ else if (add_flush_bucket) {
+ rv = send_output_flush(*(wb->filters));
+ }
+
+ return rv;
+}
+
+MP_INLINE apr_status_t modperl_wbucket_write(pTHX_ modperl_wbucket_t *wb,
+ const char *buf,
+ apr_size_t *wlen)
+{
+ apr_size_t len = *wlen;
+ *wlen = 0;
+
+ if ((len + wb->outcnt) > sizeof(wb->outbuf)) {
+ apr_status_t rv;
+ if ((rv = modperl_wbucket_flush(wb, FALSE)) != APR_SUCCESS) {
+ return rv;
+ }
+ }
+
+ if (len >= sizeof(wb->outbuf)) {
+ *wlen = len;
+ return modperl_wbucket_pass(wb, buf, len, FALSE);
+ }
+ else {
+ memcpy(&wb->outbuf[wb->outcnt], buf, len);
+ wb->outcnt += len;
+ *wlen = len;
+ return APR_SUCCESS;
+ }
+}
+
+/* generic filter routines */
+
+/* all ap_filter_t filter cleanups should go here */
+static apr_status_t modperl_filter_f_cleanup(void *data)
+{
+ ap_filter_t *f = (ap_filter_t *)data;
+ modperl_filter_ctx_t *ctx = (modperl_filter_ctx_t *)(f->ctx);
+
+ /* mod_perl filter ctx cleanup */
+ if (ctx->data){
+#ifdef USE_ITHREADS
+ dTHXa(ctx->interp->perl);
+// MP_ASSERT_CONTEXT(aTHX);
+#endif
+ if (SvOK(ctx->data) && SvREFCNT(ctx->data)) {
+ SvREFCNT_dec(ctx->data);
+ ctx->data = NULL;
+ }
+ MP_INTERP_PUTBACK(ctx->interp, aTHX);
+ }
+
+ return APR_SUCCESS;
+}
+
+modperl_filter_t *modperl_filter_new(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ modperl_filter_mode_e mode,
+ ap_input_mode_t input_mode,
+ apr_read_type_e block,
+ apr_off_t readbytes)
+{
+ apr_pool_t *p = MP_FILTER_POOL(f);
+ apr_pool_t *temp_pool;
+ modperl_filter_t *filter;
+
+ /* we can't allocate memory from the pool here, since potentially
+ * a filter can be called hundreds of times during the same
+ * request/connection resulting in enormous memory demands
+ * (sizeof(*filter)*number of invocations). so we use a sub-pool
+ * which will get destroyed at the end of each modperl_filter
+ * invocation.
+ */
+ apr_status_t rv = apr_pool_create(&temp_pool, p);
+ if (rv != APR_SUCCESS) {
+ /* XXX: how do we handle the error? assert? */
+ return NULL;
+ }
+ filter = (modperl_filter_t *)apr_pcalloc(temp_pool, sizeof(*filter));
+
+#ifdef MP_DEBUG
+ apr_pool_tag(temp_pool, "mod_perl temp filter");
+#endif
+
+ filter->temp_pool = temp_pool;
+ filter->mode = mode;
+ filter->f = f;
+ filter->pool = p;
+ filter->wbucket = NULL;
+
+ if (mode == MP_INPUT_FILTER_MODE) {
+ filter->bb_in = NULL;
+ filter->bb_out = bb;
+ filter->input_mode = input_mode;
+ filter->block = block;
+ filter->readbytes = readbytes;
+ }
+ else {
+ filter->bb_in = bb;
+ filter->bb_out = NULL;
+ }
+
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "new: %s %s filter (modperl_filter_t *0x%lx), "
+ "f (ap_filter_t *0x%lx)",
+ MP_FILTER_NAME(f),
+ MP_FILTER_TYPE(filter),
+ MP_FILTER_MODE(filter),
+ (unsigned long)filter,
+ (unsigned long)filter->f);
+
+ return filter;
+}
+
+static void modperl_filter_mg_set(pTHX_ SV *obj, modperl_filter_t *filter)
+{
+ sv_magic(SvRV(obj), (SV *)NULL, PERL_MAGIC_ext, NULL, -1);
+ SvMAGIC(SvRV(obj))->mg_ptr = (char *)filter;
+}
+
+modperl_filter_t *modperl_filter_mg_get(pTHX_ SV *obj)
+{
+ MAGIC *mg = mg_find(SvRV(obj), PERL_MAGIC_ext);
+ return mg ? (modperl_filter_t *)mg->mg_ptr : NULL;
+}
+
+/* eval "package Foo; \&init_handler" */
+int modperl_filter_resolve_init_handler(pTHX_ modperl_handler_t *handler,
+ apr_pool_t *p)
+{
+ char *init_handler_pv_code = NULL;
+
+ if (handler->mgv_cv) {
+ GV *gv = modperl_mgv_lookup(aTHX_ handler->mgv_cv);
+ if (gv) {
+ CV *cv = modperl_mgv_cv(gv);
+ if (cv && SvMAGICAL(cv)) {
+ MAGIC *mg = mg_find((SV*)(cv), PERL_MAGIC_ext);
+ init_handler_pv_code = mg ? mg->mg_ptr : NULL;
+ }
+ else {
+ /* XXX: should we complain in such a case? */
+ return 0;
+ }
+ }
+ }
+
+ if (init_handler_pv_code) {
+ char *package_name =
+ modperl_mgv_as_string(aTHX_ handler->mgv_cv, p, 1);
+ /* fprintf(stderr, "PACKAGE: %s\n", package_name ); */
+
+ /* eval the code in the parent handler's package's context */
+ char *code = apr_pstrcat(p, "package ", package_name, ";",
+ init_handler_pv_code, NULL);
+ SV *sv;
+ modperl_handler_t *init_handler;
+
+ ENTER;SAVETMPS;
+ sv = eval_pv(code, TRUE);
+ /* fprintf(stderr, "code: %s\n", code); */
+ init_handler = modperl_handler_new_from_sv(aTHX_ p, sv);
+ FREETMPS;LEAVE;
+
+ if (init_handler) {
+ modperl_mgv_resolve(aTHX_ init_handler, p, init_handler->name, 1);
+
+ MP_TRACE_h(MP_FUNC, "found init handler %s",
+ modperl_handler_name(init_handler));
+
+ if (!(init_handler->attrs & MP_FILTER_INIT_HANDLER)) {
+ Perl_croak(aTHX_ "handler %s doesn't have "
+ "the FilterInitHandler attribute set",
+ modperl_handler_name(init_handler));
+ }
+
+ handler->next = init_handler;
+ return 1;
+ }
+ else {
+ Perl_croak(aTHX_ "failed to eval code: %s", code);
+
+ }
+ }
+
+ return 1;
+}
+
+static int modperl_run_filter_init(ap_filter_t *f,
+ modperl_filter_mode_e mode,
+ modperl_handler_t *handler)
+{
+ AV *args = (AV *)NULL;
+ int status;
+
+ request_rec *r = f->r;
+ conn_rec *c = f->c;
+ server_rec *s = r ? r->server : c->base_server;
+ apr_pool_t *p = r ? r->pool : c->pool;
+ modperl_filter_t *filter = modperl_filter_new(f, NULL, mode, 0, 0, 0);
+
+ MP_dINTERPa(r, c, s);
+
+ MP_TRACE_h(MP_FUNC, "running filter init handler %s",
+ modperl_handler_name(handler));
+
+ modperl_handler_make_args(aTHX_ &args,
+ "Apache2::Filter", f,
+ NULL);
+
+ modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter);
+
+ /* XXX filter_init return status is propagated back to Apache over
+ * in C land, making it possible to use filter_init to return, say,
+ * BAD_REQUEST. this implementation, however, ignores the return status
+ * even though we're trapping it here - modperl_filter_add_request sees
+ * the error and propagates it, but modperl_output_filter_add_request
+ * is void so the error is lost */
+ if ((status = modperl_callback(aTHX_ handler, p, r, s, args)) != OK) {
+ status = modperl_errsv(aTHX_ status, r, s);
+ }
+
+ FILTER_FREE(filter);
+ SvREFCNT_dec((SV*)args);
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "return: %d", modperl_handler_name(handler), status);
+
+ return status;
+}
+
+int modperl_run_filter(modperl_filter_t *filter)
+{
+ AV *args = (AV *)NULL;
+ SV *errsv = (SV *)NULL;
+ int status;
+ modperl_handler_t *handler =
+ ((modperl_filter_ctx_t *)filter->f->ctx)->handler;
+
+ request_rec *r = filter->f->r;
+ conn_rec *c = filter->f->c;
+ server_rec *s = r ? r->server : c->base_server;
+ apr_pool_t *p = r ? r->pool : c->pool;
+
+ MP_dINTERPa(r, c, s);
+
+ MP_FILTER_SAVE_ERRSV(errsv);
+
+ modperl_handler_make_args(aTHX_ &args,
+ "Apache2::Filter", filter->f,
+ "APR::Brigade",
+ (filter->mode == MP_INPUT_FILTER_MODE
+ ? filter->bb_out
+ : filter->bb_in),
+ NULL);
+
+ modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter);
+
+ if (filter->mode == MP_INPUT_FILTER_MODE) {
+ av_push(args, newSViv(filter->input_mode));
+ av_push(args, newSViv(filter->block));
+ av_push(args, newSViv(filter->readbytes));
+ }
+
+ /* while filters are VOID handlers, we need to log any errors,
+ * because most perl coders will forget to check the return errors
+ * from read() and print() calls. and if the caller is not a perl
+ * program they won't make any sense of ERRSV or $!
+ */
+ if ((status = modperl_callback(aTHX_ handler, p, r, s, args)) != OK) {
+ status = modperl_errsv(aTHX_ status, r, s);
+ }
+
+ SvREFCNT_dec((SV*)args);
+
+ /* when the streaming filter is invoked it should be able to send
+ * extra data, after the read in a while() loop is finished.
+ * Therefore we need to postpone propogating the EOS bucket, up
+ * until the filter handler is returned and only then send the EOS
+ * bucket if the stream had one.
+ */
+ if (filter->seen_eos) {
+ filter->eos = 1;
+ filter->seen_eos = 0;
+ }
+
+ if (filter->mode == MP_INPUT_FILTER_MODE) {
+ if (filter->bb_in) {
+ if (status == DECLINED) {
+ /* make sure the filter doesn't try to make mod_perl
+ * pass the bucket brigade through after it called
+ * $f->read(), since it causes a pre-fetch of the
+ * bb */
+ MP_CROAK_PUTBACK(MODPERL_FILTER_ERROR,
+ "a filter calling $f->read "
+ "must return OK and not DECLINED");
+ }
+ /* in the streaming mode filter->bb_in is populated on the
+ * first modperl_input_filter_read, so it must be
+ * destroyed at the end of the filter invocation
+ */
+ apr_brigade_destroy(filter->bb_in);
+ filter->bb_in = NULL;
+ }
+ MP_RUN_CROAK_RESET_OK_PUTBACK(s, modperl_input_filter_flush(filter),
+ "Apache2::Filter internal flush");
+ }
+ else {
+ MP_RUN_CROAK_RESET_OK_PUTBACK(s, modperl_output_filter_flush(filter),
+ "Apache2::Filter internal flush");
+ }
+
+ MP_FILTER_RESTORE_ERRSV(errsv);
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "return: %d", modperl_handler_name(handler), status);
+
+ return status;
+}
+
+/* unrolled APR_BRIGADE_FOREACH loop */
+
+#define MP_FILTER_EMPTY(filter) \
+ APR_BRIGADE_EMPTY(filter->bb_in)
+
+#define MP_FILTER_SENTINEL(filter) \
+ APR_BRIGADE_SENTINEL(filter->bb_in)
+
+#define MP_FILTER_FIRST(filter) \
+ APR_BRIGADE_FIRST(filter->bb_in)
+
+#define MP_FILTER_NEXT(filter) \
+ APR_BUCKET_NEXT(filter->bucket)
+
+#define MP_FILTER_IS_EOS(filter) \
+ APR_BUCKET_IS_EOS(filter->bucket)
+
+#define MP_FILTER_IS_FLUSH(filter) \
+ APR_BUCKET_IS_FLUSH(filter->bucket)
+
+MP_INLINE static int get_bucket(modperl_filter_t *filter)
+{
+ if (!filter->bb_in || MP_FILTER_EMPTY(filter)) {
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "read in: bucket brigade is empty",
+ MP_FILTER_NAME(filter->f));
+ return 0;
+ }
+
+ if (!filter->bucket) {
+ filter->bucket = MP_FILTER_FIRST(filter);
+ }
+ else if (filter->bucket != MP_FILTER_SENTINEL(filter)) {
+ filter->bucket = MP_FILTER_NEXT(filter);
+ }
+
+ if (filter->bucket == MP_FILTER_SENTINEL(filter)) {
+ filter->bucket = NULL;
+ /* can't destroy bb_in since the next read will need a brigade
+ * to try to read from */
+ apr_brigade_cleanup(filter->bb_in);
+ return 0;
+ }
+
+ if (MP_FILTER_IS_EOS(filter)) {
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "read in: EOS bucket",
+ MP_FILTER_NAME(filter->f));
+
+ filter->seen_eos = 1;
+ /* there should be only one EOS sent, modperl_filter_read will
+ * not come here, since filter->seen_eos is set
+ */
+ return 0;
+ }
+ else if (MP_FILTER_IS_FLUSH(filter)) {
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "read in: FLUSH bucket",
+ MP_FILTER_NAME(filter->f));
+ filter->flush = 1;
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+
+MP_INLINE static apr_size_t modperl_filter_read(pTHX_
+ modperl_filter_t *filter,
+ SV *buffer,
+ apr_size_t wanted)
+{
+ int num_buckets = 0;
+ apr_size_t len = 0;
+
+ (void)SvUPGRADE(buffer, SVt_PV);
+ SvCUR(buffer) = 0;
+
+ /* calling SvPOK_only here may leave buffer an invalid state since
+ * SvPVX may be NULL. But it's very likely that something is copied.
+ * So, we turn the POK flag on here. Later we check if SvPVX is NULL
+ * and turn the flag off again if so. */
+ SvPOK_only(buffer);
+
+ /* sometimes the EOS bucket arrives in the same brigade with other
+ * buckets, so that particular read() will not return 0 and will
+ * be called again if called in the while ($filter->read(...))
+ * loop. In that case we return 0.
+ */
+ if (filter->seen_eos) {
+ return 0;
+ }
+
+ /* modperl_brigade_dump(filter->bb_in, NULL); */
+
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "wanted: %db",
+ MP_FILTER_NAME(filter->f),
+ wanted);
+
+ if (filter->remaining) {
+ if (filter->remaining >= wanted) {
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "eating and returning %d [%s]\n\tof "
+ "remaining %db",
+ MP_FILTER_NAME(filter->f),
+ wanted,
+ MP_TRACE_STR_TRUNC(filter->pool, filter->leftover, wanted),
+ filter->remaining);
+ SvGROW(buffer, wanted+1);
+ sv_catpvn(buffer, filter->leftover, wanted);
+ filter->leftover += wanted;
+ filter->remaining -= wanted;
+ return wanted;
+ }
+ else {
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "eating remaining %db",
+ MP_FILTER_NAME(filter->f),
+ filter->remaining);
+ SvGROW(buffer, filter->remaining+1);
+ sv_catpvn(buffer, filter->leftover, filter->remaining);
+ len = filter->remaining;
+ filter->remaining = 0;
+ filter->leftover = NULL;
+ }
+ }
+
+ while (1) {
+ const char *buf;
+ apr_size_t buf_len;
+
+ if (!get_bucket(filter)) {
+ break;
+ }
+
+ num_buckets++;
+
+ filter->rc = apr_bucket_read(filter->bucket, &buf, &buf_len, 0);
+
+ if (filter->rc == APR_SUCCESS) {
+ MP_TRACE_f(MP_FUNC,
+ MP_FILTER_NAME_FORMAT
+ "read in: %s bucket with %db (0x%lx)",
+ MP_FILTER_NAME(filter->f),
+ filter->bucket->type->name,
+ buf_len,
+ (unsigned long)filter->bucket);
+ }
+ else {
+ SvREFCNT_dec(buffer);
+ modperl_croak(aTHX_ filter->rc, "Apache2::Filter::read");
+ }
+
+ if (buf_len) {
+ if ((SvCUR(buffer) + buf_len) >= wanted) {
+ int nibble = wanted - SvCUR(buffer);
+ SvGROW(buffer, SvCUR(buffer)+nibble+1);
+ sv_catpvn(buffer, buf, nibble);
+ filter->leftover = (char *)buf+nibble;
+ filter->remaining = buf_len - nibble;
+ len += nibble;
+ break;
+ }
+ else {
+ len += buf_len;
+ SvGROW(buffer, SvCUR(buffer)+buf_len+1);
+ sv_catpvn(buffer, buf, buf_len);
+ }
+ }
+ }
+
+ if (!SvPVX(buffer)) {
+ SvPOK_off(buffer);
+ }
+
+ MP_TRACE_f(MP_FUNC,
+ MP_FILTER_NAME_FORMAT
+ "return: %db from %d bucket%s [%s]\n\t(%db leftover)",
+ MP_FILTER_NAME(filter->f),
+ len, num_buckets, ((num_buckets == 1) ? "" : "s"),
+ MP_TRACE_STR_TRUNC(filter->pool, SvPVX(buffer), len),
+ filter->remaining);
+
+ return len;
+}
+
+MP_INLINE apr_size_t modperl_input_filter_read(pTHX_
+ modperl_filter_t *filter,
+ SV *buffer,
+ apr_size_t wanted)
+{
+ apr_size_t len = 0;
+
+ if (!filter->bb_in) {
+ /* This should be read only once per handler invocation! */
+ filter->bb_in = apr_brigade_create(filter->pool,
+ filter->f->c->bucket_alloc);
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "retrieving bb: 0x%lx",
+ MP_FILTER_NAME(filter->f),
+ (unsigned long)(filter->bb_in));
+ MP_RUN_CROAK(ap_get_brigade(filter->f->next, filter->bb_in,
+ filter->input_mode, filter->block,
+ filter->readbytes),
+ "Apache2::Filter::read");
+ }
+
+ len = modperl_filter_read(aTHX_ filter, buffer, wanted);
+
+ if (filter->flush && len == 0) {
+ /* if len > 0 then $filter->write will flush */
+ apr_status_t rc = modperl_input_filter_flush(filter);
+ if (rc != APR_SUCCESS) {
+ SvREFCNT_dec(buffer);
+ modperl_croak(aTHX_ rc, "Apache2::Filter::read");
+ }
+ }
+
+ return len;
+}
+
+
+MP_INLINE apr_size_t modperl_output_filter_read(pTHX_
+ modperl_filter_t *filter,
+ SV *buffer,
+ apr_size_t wanted)
+{
+ apr_size_t len = 0;
+ len = modperl_filter_read(aTHX_ filter, buffer, wanted);
+
+ if (filter->flush && len == 0) {
+ /* if len > 0 then $filter->write will flush */
+ apr_status_t rc = modperl_output_filter_flush(filter);
+ if (rc != APR_SUCCESS) {
+ SvREFCNT_dec(buffer);
+ modperl_croak(aTHX_ rc, "Apache2::Filter::read");
+ }
+ }
+
+ return len;
+}
+
+
+MP_INLINE apr_status_t modperl_input_filter_flush(modperl_filter_t *filter)
+{
+ if (((modperl_filter_ctx_t *)filter->f->ctx)->sent_eos) {
+ /* no data should be sent after EOS has been sent */
+ return filter->rc;
+ }
+
+ if (filter->flush) {
+ filter->rc = send_input_flush(filter);
+ filter->flush = 0;
+ }
+
+ if (filter->eos) {
+ filter->rc = send_input_eos(filter);
+ filter->eos = 0;
+ }
+
+ return filter->rc;
+}
+
+MP_INLINE apr_status_t modperl_output_filter_flush(modperl_filter_t *filter)
+{
+ int add_flush_bucket = FALSE;
+
+ if (((modperl_filter_ctx_t *)filter->f->ctx)->sent_eos) {
+ /* no data should be sent after EOS has been sent */
+ return filter->rc;
+ }
+
+ if (filter->flush) {
+ add_flush_bucket = TRUE;
+ filter->flush = 0;
+ }
+
+ WBUCKET_INIT(filter);
+ filter->rc = modperl_wbucket_flush(filter->wbucket, add_flush_bucket);
+ if (filter->rc != APR_SUCCESS) {
+ return filter->rc;
+ }
+
+ if (filter->eos) {
+ filter->rc = send_output_eos(filter->f);
+ if (filter->bb_in) {
+ apr_brigade_destroy(filter->bb_in);
+ filter->bb_in = NULL;
+ }
+ filter->eos = 0;
+ }
+
+ return filter->rc;
+}
+
+MP_INLINE apr_status_t modperl_input_filter_write(pTHX_
+ modperl_filter_t *filter,
+ const char *buf,
+ apr_size_t *len)
+{
+ apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc;
+ char *copy = apr_pmemdup(filter->pool, buf, *len);
+ apr_bucket *bucket = apr_bucket_transient_create(copy, *len, ba);
+ MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
+ "write out: %db [%s]:",
+ MP_FILTER_NAME(filter->f), *len,
+ MP_TRACE_STR_TRUNC(filter->pool, copy, *len));
+ APR_BRIGADE_INSERT_TAIL(filter->bb_out, bucket);
+ /* modperl_brigade_dump(filter->bb_out, NULL); */
+ return APR_SUCCESS;
+}
+
+MP_INLINE apr_status_t modperl_output_filter_write(pTHX_
+ modperl_filter_t *filter,
+ const char *buf,
+ apr_size_t *len)
+{
+ WBUCKET_INIT(filter);
+
+ return modperl_wbucket_write(aTHX_ filter->wbucket, buf, len);
+}
+
+apr_status_t modperl_output_filter_handler(ap_filter_t *f,
+ apr_bucket_brigade *bb)
+{
+ modperl_filter_t *filter;
+ int status;
+
+ if (((modperl_filter_ctx_t *)f->ctx)->sent_eos) {
+ MP_TRACE_f(MP_FUNC,
+ MP_FILTER_NAME_FORMAT
+ "write_out: EOS was already sent, "
+ "passing through the brigade",
+ MP_FILTER_NAME(f));
+ return ap_pass_brigade(f->next, bb);
+ }
+ else {
+ filter = modperl_filter_new(f, bb, MP_OUTPUT_FILTER_MODE,
+ 0, 0, 0);
+ status = modperl_run_filter(filter);
+ FILTER_FREE(filter);
+ }
+
+ switch (status) {
+ case OK:
+ return APR_SUCCESS;
+ case DECLINED:
+ return ap_pass_brigade(f->next, bb);
+ default:
+ return status; /*XXX*/
+ }
+}
+
+apr_status_t modperl_input_filter_handler(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ ap_input_mode_t input_mode,
+ apr_read_type_e block,
+ apr_off_t readbytes)
+{
+ modperl_filter_t *filter;
+ int status;
+
+ if (((modperl_filter_ctx_t *)f->ctx)->sent_eos) {
+ MP_TRACE_f(MP_FUNC,
+ MP_FILTER_NAME_FORMAT
+ "write out: EOS was already sent, "
+ "passing through the brigade",
+ MP_FILTER_NAME(f));
+ return ap_get_brigade(f->next, bb, input_mode, block, readbytes);
+ }
+ else {
+ filter = modperl_filter_new(f, bb, MP_INPUT_FILTER_MODE,
+ input_mode, block, readbytes);
+ status = modperl_run_filter(filter);
+ FILTER_FREE(filter);
+ }
+
+ switch (status) {
+ case OK:
+ return APR_SUCCESS;
+ case DECLINED:
+ return ap_get_brigade(f->next, bb, input_mode, block, readbytes);
+ case HTTP_INTERNAL_SERVER_ERROR:
+ /* XXX: later may introduce separate error codes for
+ * modperl_run_filter and modperl_run_filter_init */
+ return MODPERL_FILTER_ERROR;
+ default:
+ return status; /*XXX*/
+ }
+}
+
+static int modperl_filter_add_connection(conn_rec *c,
+ int idx,
+ const char *name,
+ modperl_filter_add_t addfunc,
+ const char *type)
+{
+ modperl_config_dir_t *dcfg =
+ modperl_config_dir_get_defaults(c->base_server);
+ MpAV *av;
+
+ if ((av = dcfg->handlers_per_dir[idx])) {
+ modperl_handler_t **handlers = (modperl_handler_t **)av->elts;
+ int i;
+
+ for (i=0; i<av->nelts; i++) {
+ modperl_filter_ctx_t *ctx;
+ ap_filter_t *f;
+
+ /* process non-mod_perl filter handlers */
+ if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) {
+
+ /* non-mp2 filters below PROTOCOL level can't be added
+ * at the connection level, so we need to go through
+ * the pain of figuring out the type of the filter */
+ ap_filter_rec_t *frec;
+ char *normalized_name = apr_pstrdup(c->pool,
+ handlers[i]->name);
+ ap_str_tolower(normalized_name);
+ frec = idx == MP_INPUT_FILTER_HANDLER
+ ? ap_get_input_filter_handle(normalized_name)
+ : ap_get_output_filter_handle(normalized_name);
+ if (frec && frec->ftype < AP_FTYPE_PROTOCOL) {
+ MP_TRACE_f(MP_FUNC, "a non-mod_perl %s handler %s "
+ "skipped (not a connection filter)",
+ type, handlers[i]->name);
+ continue;
+ }
+
+ addfunc(handlers[i]->name, NULL, NULL, c);
+ MP_TRACE_f(MP_FUNC,
+ "a non-mod_perl %s handler %s configured "
+ "(connection)", type, handlers[i]->name);
+ continue;
+ }
+
+ /* skip non-connection level filters, e.g. request filters
+ * configured outside the resource container */
+ if (!(handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) {
+ MP_TRACE_f(MP_FUNC,
+ "%s is not a FilterConnection handler, skipping",
+ handlers[i]->name);
+ continue;
+ }
+
+ ctx = (modperl_filter_ctx_t *)apr_pcalloc(c->pool, sizeof(*ctx));
+ ctx->handler = handlers[i];
+
+ f = addfunc(name, (void*)ctx, NULL, c);
+
+ /* ap_filter_t filter cleanup */
+ apr_pool_cleanup_register(c->pool, (void *)f,
+ modperl_filter_f_cleanup,
+ apr_pool_cleanup_null);
+
+ if (handlers[i]->attrs & MP_FILTER_HAS_INIT_HANDLER &&
+ handlers[i]->next) {
+ int status = modperl_run_filter_init(
+ f,
+ (idx == MP_INPUT_FILTER_HANDLER
+ ? MP_INPUT_FILTER_MODE : MP_OUTPUT_FILTER_MODE),
+ handlers[i]->next);
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ MP_TRACE_h(MP_FUNC, "%s handler %s configured (connection)",
+ type, handlers[i]->name);
+ }
+
+ return OK;
+ }
+
+ MP_TRACE_h(MP_FUNC, "no %s handlers configured (connection)", type);
+
+ return DECLINED;
+}
+
+static int modperl_filter_add_request(request_rec *r,
+ int idx,
+ const char *name,
+ modperl_filter_add_t addfunc,
+ const char *type,
+ ap_filter_t *filters)
+{
+ MP_dDCFG;
+ MpAV *av;
+
+ if ((av = dcfg->handlers_per_dir[idx])) {
+ modperl_handler_t **handlers = (modperl_handler_t **)av->elts;
+ int i;
+
+ for (i=0; i<av->nelts; i++) {
+ modperl_filter_ctx_t *ctx;
+ int registered = 0;
+ ap_filter_t *f;
+
+ /* process non-mod_perl filter handlers */
+ if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) {
+ addfunc(handlers[i]->name, NULL, r, r->connection);
+ MP_TRACE_f(MP_FUNC,
+ "a non-mod_perl %s handler %s configured (%s)",
+ type, handlers[i]->name, r->uri);
+ continue;
+ }
+
+ /* skip non-request level filters, e.g. connection filters
+ * configured outside the resource container, merged into
+ * resource's dcfg->handlers_per_dir[] entry.
+ */
+ if ((handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) {
+ MP_TRACE_f(MP_FUNC,
+ "%s is not a FilterRequest handler, skipping",
+ handlers[i]->name);
+ continue;
+ }
+
+ /* XXX: I fail to see where this feature is used, since
+ * modperl_filter_add_connection doesn't register request
+ * filters. may be it'll be still useful when the same
+ * filter handler is configured to run more than once?
+ * e.g. snooping filter [stas] */
+ f = filters;
+ while (f) {
+ const char *fname = f->frec->name;
+
+ /* XXX: I think this won't work as f->frec->name gets
+ * lowercased when added to the chain */
+ if (*fname == 'M' && strEQ(fname, name)) {
+ modperl_handler_t *ctx_handler =
+ ((modperl_filter_ctx_t *)f->ctx)->handler;
+
+ if (modperl_handler_equal(ctx_handler, handlers[i])) {
+ /* skip if modperl_filter_add_connection
+ * already registered this handler
+ * XXX: set a flag in the modperl_handler_t instead
+ */
+ registered = 1;
+ break;
+ }
+ }
+
+ f = f->next;
+ }
+
+ if (registered) {
+ MP_TRACE_f(MP_FUNC,
+ "%s %s already registered",
+ handlers[i]->name, type);
+ continue;
+ }
+
+ ctx = (modperl_filter_ctx_t *)apr_pcalloc(r->pool, sizeof(*ctx));
+ ctx->handler = handlers[i];
+
+ f = addfunc(name, (void*)ctx, r, r->connection);
+
+ /* ap_filter_t filter cleanup */
+ apr_pool_cleanup_register(r->pool, (void *)f,
+ modperl_filter_f_cleanup,
+ apr_pool_cleanup_null);
+
+ if (handlers[i]->attrs & MP_FILTER_HAS_INIT_HANDLER &&
+ handlers[i]->next) {
+ int status = modperl_run_filter_init(
+ f,
+ (idx == MP_INPUT_FILTER_HANDLER
+ ? MP_INPUT_FILTER_MODE : MP_OUTPUT_FILTER_MODE),
+ handlers[i]->next);
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ MP_TRACE_h(MP_FUNC, "%s handler %s configured (%s)",
+ type, handlers[i]->name, r->uri);
+ }
+
+ return OK;
+ }
+
+ MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)",
+ type, r->uri);
+
+ return DECLINED;
+}
+
+void modperl_output_filter_add_connection(conn_rec *c)
+{
+ modperl_filter_add_connection(c,
+ MP_OUTPUT_FILTER_HANDLER,
+ MP_FILTER_CONNECTION_OUTPUT_NAME,
+ ap_add_output_filter,
+ "OutputFilter");
+}
+
+void modperl_output_filter_add_request(request_rec *r)
+{
+ modperl_filter_add_request(r,
+ MP_OUTPUT_FILTER_HANDLER,
+ MP_FILTER_REQUEST_OUTPUT_NAME,
+ ap_add_output_filter,
+ "OutputFilter",
+ r->connection->output_filters);
+}
+
+void modperl_input_filter_add_connection(conn_rec *c)
+{
+ modperl_filter_add_connection(c,
+ MP_INPUT_FILTER_HANDLER,
+ MP_FILTER_CONNECTION_INPUT_NAME,
+ ap_add_input_filter,
+ "InputFilter");
+}
+
+void modperl_input_filter_add_request(request_rec *r)
+{
+ modperl_filter_add_request(r,
+ MP_INPUT_FILTER_HANDLER,
+ MP_FILTER_REQUEST_INPUT_NAME,
+ ap_add_input_filter,
+ "InputFilter",
+ r->connection->input_filters);
+}
+
+void modperl_filter_runtime_add(pTHX_ request_rec *r, conn_rec *c,
+ const char *name,
+ modperl_filter_mode_e mode,
+ modperl_filter_add_t addfunc,
+ SV *callback, const char *type)
+{
+ apr_pool_t *pool = r ? r->pool : c->pool;
+ modperl_handler_t *handler =
+ modperl_handler_new_from_sv(aTHX_ pool, callback);
+
+ if (handler) {
+ ap_filter_t *f;
+ modperl_filter_ctx_t *ctx =
+ (modperl_filter_ctx_t *)apr_pcalloc(pool, sizeof(*ctx));
+
+ ctx->handler = handler;
+ f = addfunc(name, (void*)ctx, r, c);
+
+ /* ap_filter_t filter cleanup */
+ apr_pool_cleanup_register(pool, (void *)f,
+ modperl_filter_f_cleanup,
+ apr_pool_cleanup_null);
+
+ /* has to resolve early so we can check for init functions */
+ if (!modperl_mgv_resolve(aTHX_ handler, pool, handler->name, TRUE)) {
+ Perl_croak(aTHX_ "unable to resolve handler %s\n",
+ modperl_handler_name(handler));
+ }
+
+ /* verify that the filter handler is of the right kind */
+ if (r == NULL) {
+ /* needs to have the FilterConnectionHandler attribute */
+ if (!(handler->attrs & MP_FILTER_CONNECTION_HANDLER)) {
+ Perl_croak(aTHX_ "Can't add connection filter handler '%s' "
+ "since it doesn't have the "
+ "FilterConnectionHandler attribute set",
+ modperl_handler_name(handler));
+ }
+ }
+ else {
+ /* needs to have the FilterRequestHandler attribute, but
+ * since by default request filters are not required to
+ * have the FilterRequestHandler attribute, croak only if
+ * some other attribute is set, but not
+ * FilterRequestHandler */
+ if (handler->attrs &&
+ !(handler->attrs & MP_FILTER_REQUEST_HANDLER)) {
+ Perl_croak(aTHX_ "Can't add request filter handler '%s' "
+ "since it doesn't have the "
+ "FilterRequestHandler attribute set",
+ modperl_handler_name(handler));
+ }
+ }
+
+ if (handler->attrs & MP_FILTER_HAS_INIT_HANDLER && handler->next) {
+ int status = modperl_run_filter_init(f, mode, handler->next);
+ if (status != OK) {
+ modperl_croak(aTHX_ status, strEQ("InputFilter", type)
+ ? "Apache2::Filter::add_input_filter"
+ : "Apache2::Filter::add_output_filter");
+ }
+ }
+
+ MP_TRACE_h(MP_FUNC, "%s handler %s configured (connection)",
+ type, name);
+
+ return;
+ }
+
+ Perl_croak(aTHX_ "unable to resolve handler 0x%lx\n",
+ (unsigned long)callback);
+}
+
+void modperl_brigade_dump(apr_bucket_brigade *bb, apr_file_t *file)
+{
+ apr_bucket *bucket;
+ int i = 0;
+#ifndef WIN32
+ if (file == NULL) {
+ file = modperl_global_get_server_rec()->error_log;
+ }
+
+ apr_file_printf(file, "dump of brigade 0x%lx\n", (unsigned long)bb);
+
+ for (bucket = APR_BRIGADE_FIRST(bb);
+ bucket != APR_BRIGADE_SENTINEL(bb);
+ bucket = APR_BUCKET_NEXT(bucket))
+ {
+ apr_file_printf(file,
+ " %d: bucket=%s(0x%lx), length=%ld, data=0x%lx\n",
+ i, bucket->type->name,
+ (unsigned long)bucket,
+ (long)bucket->length,
+ (unsigned long)bucket->data);
+ /* apr_file_printf(file, " : %s\n", (char *)bucket->data); */
+
+ i++;
+ }
+#endif
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_filter.h b/2_0_13/src/modules/perl/modperl_filter.h
new file mode 100644
index 0000000..939f054
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_filter.h
@@ -0,0 +1,123 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_FILTER_H
+#define MODPERL_FILTER_H
+
+#define MP_FILTER_CONNECTION_OUTPUT_NAME "MODPERL_CONNECTION_OUTPUT"
+#define MP_FILTER_CONNECTION_INPUT_NAME "MODPERL_CONNECTION_INPUT"
+
+#define MP_FILTER_REQUEST_OUTPUT_NAME "MODPERL_REQUEST_OUTPUT"
+#define MP_FILTER_REQUEST_INPUT_NAME "MODPERL_REQUEST_INPUT"
+
+#define MP_FILTER_CONNECTION_HANDLER 0x01
+#define MP_FILTER_REQUEST_HANDLER 0x02
+#define MP_FILTER_HAS_INIT_HANDLER 0x04
+#define MP_FILTER_INIT_HANDLER 0x08
+#define MP_FILTER_HTTPD_HANDLER 0x10
+
+typedef ap_filter_t * MP_FUNC_T(modperl_filter_add_t) (const char *, void *,
+ request_rec *,
+ conn_rec *);
+
+/* simple buffer api */
+MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *b,
+ const char *buf, apr_size_t len,
+ int add_flush_bucket);
+
+MP_INLINE apr_status_t modperl_wbucket_flush(modperl_wbucket_t *b,
+ int add_flush_bucket);
+
+MP_INLINE apr_status_t modperl_wbucket_write(pTHX_
+ modperl_wbucket_t *b,
+ const char *buf,
+ apr_size_t *wlen);
+
+/* generic filter routines */
+
+modperl_filter_t *modperl_filter_new(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ modperl_filter_mode_e mode,
+ ap_input_mode_t input_mode,
+ apr_read_type_e block,
+ apr_off_t readbytes);
+
+modperl_filter_t *modperl_filter_mg_get(pTHX_ SV *obj);
+
+int modperl_filter_resolve_init_handler(pTHX_ modperl_handler_t *handler,
+ apr_pool_t *p);
+
+int modperl_run_filter(modperl_filter_t *filter);
+
+/* output filters */
+apr_status_t modperl_output_filter_handler(ap_filter_t *f,
+ apr_bucket_brigade *bb);
+
+void modperl_output_filter_add_connection(conn_rec *c);
+
+void modperl_output_filter_add_request(request_rec *r);
+
+MP_INLINE apr_status_t modperl_output_filter_flush(modperl_filter_t *filter);
+MP_INLINE apr_status_t modperl_input_filter_flush(modperl_filter_t *filter);
+
+
+MP_INLINE apr_size_t modperl_output_filter_read(pTHX_
+ modperl_filter_t *filter,
+ SV *buffer,
+ apr_size_t wanted);
+
+MP_INLINE apr_status_t modperl_output_filter_write(pTHX_
+ modperl_filter_t *filter,
+ const char *buf,
+ apr_size_t *len);
+
+void modperl_brigade_dump(apr_bucket_brigade *bb, apr_file_t *file);
+
+/* input filters */
+apr_status_t modperl_input_filter_handler(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ ap_input_mode_t input_mode,
+ apr_read_type_e block,
+ apr_off_t readbytes);
+
+void modperl_input_filter_add_connection(conn_rec *c);
+
+void modperl_input_filter_add_request(request_rec *r);
+
+MP_INLINE apr_size_t modperl_input_filter_read(pTHX_
+ modperl_filter_t *filter,
+ SV *buffer,
+ apr_size_t wanted);
+
+MP_INLINE apr_status_t modperl_input_filter_write(pTHX_
+ modperl_filter_t *filter,
+ const char *buf,
+ apr_size_t *len);
+
+void modperl_filter_runtime_add(pTHX_ request_rec *r, conn_rec *c,
+ const char *name,
+ modperl_filter_mode_e mode,
+ modperl_filter_add_t addfunc,
+ SV *callback, const char *type);
+
+#endif /* MODPERL_FILTER_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_global.c b/2_0_13/src/modules/perl/modperl_global.c
new file mode 100644
index 0000000..750110c
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_global.c
@@ -0,0 +1,312 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+void modperl_global_request_cfg_set(request_rec *r)
+{
+ MP_dDCFG;
+ MP_dRCFG;
+
+ /* only if PerlOptions +GlobalRequest and not done already */
+ if (MpDirGLOBAL_REQUEST(dcfg) && !MpReqSET_GLOBAL_REQUEST(rcfg)) {
+ modperl_global_request_set(r);
+ }
+}
+
+void modperl_global_request_set(request_rec *r)
+{
+ MP_dRCFG;
+ request_rec *old_r = NULL;
+
+ /* reset old value, important for subrequests */
+ (void)modperl_tls_get_request_rec(&old_r);
+ modperl_tls_reset_cleanup_request_rec(r->pool, old_r);
+
+ modperl_tls_set_request_rec(r);
+
+ /* so 'PerlOptions +GlobalRequest' doesnt wipe us out */
+ MpReqSET_GLOBAL_REQUEST_On(rcfg);
+}
+
+/* get/set */
+request_rec *modperl_global_request(pTHX_ SV *svr)
+{
+ request_rec *cur = NULL;
+ apr_status_t status = modperl_tls_get_request_rec(&cur);
+ if (status != APR_SUCCESS) {
+ /* an internal problem */
+ Perl_croak(aTHX_ "failed to retrieve the request object");
+ }
+
+ if (GIMME_V != G_VOID && !cur) {
+ /* wrong configuration */
+ Perl_croak(aTHX_ "Global $r object is not available. Set:\n"
+ "\tPerlOptions +GlobalRequest\nin httpd.conf");
+ }
+
+ if (svr) {
+ modperl_global_request_obj_set(aTHX_ svr);
+ }
+
+ return cur;
+}
+
+void modperl_global_request_obj_set(pTHX_ SV *svr)
+{
+ /* XXX: support sublassing */
+ request_rec *r = modperl_sv2request_rec(aTHX_ svr);
+ modperl_global_request_set(r);
+}
+
+#if MP_THREADED
+static apr_status_t modperl_global_cleanup(void *data)
+{
+ modperl_global_t *global = (modperl_global_t *)data;
+
+ MP_TRACE_g(MP_FUNC, "destroy lock for %s", global->name);
+ MUTEX_DESTROY(&global->glock);
+
+ return APR_SUCCESS;
+}
+#endif
+
+void modperl_global_init(modperl_global_t *global, apr_pool_t *p,
+ void *data, const char *name)
+{
+ Zero(global, 1, modperl_global_t);
+
+ global->data = data;
+ global->name = name;
+
+#if MP_THREADED
+ MUTEX_INIT(&global->glock);
+
+ apr_pool_cleanup_register(p, (void *)global,
+ modperl_global_cleanup,
+ apr_pool_cleanup_null);
+#endif
+
+ MP_TRACE_g(MP_FUNC, "init %s", name);
+}
+
+void modperl_global_lock(modperl_global_t *global)
+{
+#if MP_THREADED
+ MP_TRACE_g(MP_FUNC, "locking %s", global->name);
+ MUTEX_LOCK(&global->glock);
+#endif
+}
+
+void modperl_global_unlock(modperl_global_t *global)
+{
+#if MP_THREADED
+ MP_TRACE_g(MP_FUNC, "unlocking %s", global->name);
+ MUTEX_UNLOCK(&global->glock);
+#endif
+}
+
+void *modperl_global_get(modperl_global_t *global)
+{
+ return global->data;
+}
+
+void modperl_global_set(modperl_global_t *global, void *data)
+{
+ global->data = data;
+}
+
+/* hopefully there wont be many of these */
+
+#define MP_GLOBAL_IMPL(gname, type) \
+ \
+static modperl_global_t MP_global_##gname; \
+ \
+void modperl_global_init_##gname(apr_pool_t *p, \
+ type gname) \
+{ \
+ modperl_global_init(&MP_global_##gname, p, \
+ (void *)gname, #gname); \
+} \
+ \
+void modperl_global_lock_##gname(void) \
+{ \
+ modperl_global_lock(&MP_global_##gname); \
+} \
+ \
+void modperl_global_unlock_##gname(void) \
+{ \
+ modperl_global_unlock(&MP_global_##gname); \
+} \
+ \
+type modperl_global_get_##gname(void) \
+{ \
+ return (type ) \
+ modperl_global_get(&MP_global_##gname); \
+} \
+ \
+void modperl_global_set_##gname(void *data) \
+{ \
+ modperl_global_set(&MP_global_##gname, data); \
+} \
+
+MP_GLOBAL_IMPL(pconf, apr_pool_t *)
+MP_GLOBAL_IMPL(server_rec, server_rec *)
+
+
+
+
+
+/*** anon handlers code ***/
+
+static modperl_global_t MP_global_anon_cnt;
+
+void modperl_global_anon_cnt_init(apr_pool_t *p)
+{
+ int *data = (int *)apr_pcalloc(p, sizeof(int));
+ *data = 0;
+ modperl_global_init(&MP_global_anon_cnt, p, (void *)data, "anon_cnt");
+}
+
+int modperl_global_anon_cnt_next(void)
+{
+ int next;
+ /* XXX: inline lock/unlock? */
+ modperl_global_lock(&MP_global_anon_cnt);
+
+ next = ++*(int *)(MP_global_anon_cnt.data);
+
+ modperl_global_unlock(&MP_global_anon_cnt);
+
+ return next;
+}
+
+
+
+/*** TLS ***/
+
+#if MP_THREADED
+static apr_status_t modperl_tls_cleanup(void *data)
+{
+ return apr_threadkey_private_delete((apr_threadkey_t *)data);
+}
+#endif
+
+apr_status_t modperl_tls_create(apr_pool_t *p, modperl_tls_t **key)
+{
+#if MP_THREADED
+ apr_status_t status = apr_threadkey_private_create(key, NULL, p);
+ apr_pool_cleanup_register(p, (void *)*key,
+ modperl_tls_cleanup,
+ apr_pool_cleanup_null);
+ return status;
+#else
+ *key = apr_pcalloc(p, sizeof(**key));
+ return APR_SUCCESS;
+#endif
+}
+
+apr_status_t modperl_tls_get(modperl_tls_t *key, void **data)
+{
+#if MP_THREADED
+ if (!key) {
+ *data = NULL;
+ return APR_SUCCESS;
+ }
+ return apr_threadkey_private_get(data, key);
+#else
+ *data = modperl_global_get((modperl_global_t *)key);
+ return APR_SUCCESS;
+#endif
+}
+
+apr_status_t modperl_tls_set(modperl_tls_t *key, void *data)
+{
+#if MP_THREADED
+ return apr_threadkey_private_set(data, key);
+#else
+ modperl_global_set((modperl_global_t *)key, data);
+ return APR_SUCCESS;
+#endif
+}
+
+typedef struct {
+ modperl_tls_t *key;
+ void *data;
+} modperl_tls_cleanup_data_t;
+
+static apr_status_t modperl_tls_reset(void *data)
+{
+ modperl_tls_cleanup_data_t *cdata =
+ (modperl_tls_cleanup_data_t *)data;
+ return modperl_tls_set(cdata->key, cdata->data);
+}
+
+void modperl_tls_reset_cleanup(apr_pool_t *p, modperl_tls_t *key,
+ void *data)
+{
+ modperl_tls_cleanup_data_t *cdata =
+ (modperl_tls_cleanup_data_t *)apr_palloc(p, sizeof(*cdata));
+
+ cdata->key = key;
+ cdata->data = data;
+
+ apr_pool_cleanup_register(p, (void *)cdata,
+ modperl_tls_reset,
+ apr_pool_cleanup_null);
+}
+
+/* hopefully there wont be many of these either */
+
+#define MP_TLS_IMPL(gname, type) \
+ \
+static modperl_tls_t *MP_tls_##gname; \
+ \
+apr_status_t \
+modperl_tls_create_##gname(apr_pool_t *p) \
+{ \
+ return modperl_tls_create(p, &MP_tls_##gname); \
+} \
+ \
+apr_status_t modperl_tls_get_##gname(type *data) \
+{ \
+ void *ptr; \
+ apr_status_t status = \
+ modperl_tls_get(MP_tls_##gname, &ptr); \
+ *data = (type )ptr; \
+ return status; \
+} \
+ \
+apr_status_t modperl_tls_set_##gname(void *data) \
+{ \
+ return modperl_tls_set(MP_tls_##gname, data); \
+} \
+ \
+void modperl_tls_reset_cleanup_##gname(apr_pool_t *p, \
+ type data) \
+{ \
+ modperl_tls_reset_cleanup(p, MP_tls_##gname, \
+ (void *)data); \
+}
+
+MP_TLS_IMPL(request_rec, request_rec *)
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_global.h b/2_0_13/src/modules/perl/modperl_global.h
new file mode 100644
index 0000000..8d4f05a
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_global.h
@@ -0,0 +1,90 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_GLOBAL_H
+#define MODPERL_GLOBAL_H
+
+typedef struct {
+#if MP_THREADED
+ perl_mutex glock;
+#endif
+ int flags;
+ void *data;
+ const char *name;
+} modperl_global_t;
+
+#if MP_THREADED
+typedef apr_threadkey_t modperl_tls_t;
+#else
+typedef modperl_global_t modperl_tls_t;
+#endif
+
+void modperl_global_request_cfg_set(request_rec *r);
+
+request_rec *modperl_global_request(pTHX_ SV *svr);
+
+void modperl_global_request_set(request_rec *r);
+
+void modperl_global_request_obj_set(pTHX_ SV *svr);
+
+void modperl_global_init(modperl_global_t *global, apr_pool_t *p,
+ void *data, const char *name);
+
+void modperl_global_lock(modperl_global_t *global);
+
+void modperl_global_unlock(modperl_global_t *global);
+
+void *modperl_global_get(modperl_global_t *global);
+
+void modperl_global_set(modperl_global_t *global, void *data);
+
+#define MP_GLOBAL_DECL(gname, type) \
+ void modperl_global_init_##gname(apr_pool_t *p, type gname); \
+ void modperl_global_lock_##gname(void); \
+ void modperl_global_unlock_##gname(void); \
+ type modperl_global_get_##gname(void); \
+ void modperl_global_set_##gname(void *)
+
+/* modperl_global_get_pconf returns a thread un-safe object */
+MP_GLOBAL_DECL(pconf, apr_pool_t *);
+
+/* modperl_global_get_server_rec returns a thread un-safe object */
+MP_GLOBAL_DECL(server_rec, server_rec *);
+
+void modperl_global_anon_cnt_init(apr_pool_t *p);
+int modperl_global_anon_cnt_next(void);
+
+apr_status_t modperl_tls_create(apr_pool_t *p, modperl_tls_t **key);
+apr_status_t modperl_tls_get(modperl_tls_t *key, void **data);
+apr_status_t modperl_tls_set(modperl_tls_t *key, void *data);
+void modperl_tls_reset_cleanup(apr_pool_t *p, modperl_tls_t *key, void *data);
+
+#define MP_TLS_DECL(gname, type) \
+apr_status_t modperl_tls_create_##gname(apr_pool_t *p); \
+apr_status_t modperl_tls_get_##gname(type *data); \
+apr_status_t modperl_tls_set_##gname(void *data); \
+void modperl_tls_reset_cleanup_##gname(apr_pool_t *p, type data)
+
+MP_TLS_DECL(request_rec, request_rec *);
+
+#endif /* MODPERL_GLOBAL_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_gtop.c b/2_0_13/src/modules/perl/modperl_gtop.c
new file mode 100644
index 0000000..170cfd1
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_gtop.c
@@ -0,0 +1,154 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+#ifdef MP_USE_GTOP
+
+static int modperl_gtop_size_string(size_t size, char *size_string)
+{
+ if (size == (size_t)-1) {
+ apr_snprintf(size_string, MP_GTOP_SSS, "-");
+ }
+ else if (!size) {
+ apr_snprintf(size_string, MP_GTOP_SSS, "0k");
+ }
+ else if (size < 1024) {
+ apr_snprintf(size_string, MP_GTOP_SSS, "1k");
+ }
+ else if (size < 1048576) {
+ apr_snprintf(size_string, MP_GTOP_SSS, "%dk",
+ (int)(size + 512) / 1024);
+ }
+ else if (size < 103809024) {
+ apr_snprintf(size_string, MP_GTOP_SSS, "%.1fM",
+ size / 1048576.0);
+ }
+ else {
+ apr_snprintf(size_string, MP_GTOP_SSS, "%dM",
+ (int)(size + 524288) / 1048576);
+ }
+
+ return 1;
+}
+
+static apr_status_t modperl_gtop_exit(void *data)
+{
+ glibtop_close();
+ return APR_SUCCESS;
+}
+
+modperl_gtop_t *modperl_gtop_new(apr_pool_t *p)
+{
+ modperl_gtop_t *gtop =
+ (modperl_gtop_t *)apr_pcalloc(p, sizeof(*gtop));
+
+ gtop->pid = getpid();
+ glibtop_init();
+ apr_pool_cleanup_register(p, NULL,
+ modperl_gtop_exit, apr_pool_cleanup_null);
+
+ return gtop;
+}
+
+void modperl_gtop_get_proc_mem_before(modperl_gtop_t *gtop)
+{
+ glibtop_get_proc_mem(>op->before.proc_mem, gtop->pid);
+}
+
+void modperl_gtop_get_proc_mem_after(modperl_gtop_t *gtop)
+{
+ glibtop_get_proc_mem(>op->after.proc_mem, gtop->pid);
+}
+
+#define modperl_gtop_diff(item) \
+(gtop->after.item - gtop->before.item)
+
+#define ss_fmt "size=%s, vsize=%s, resident=%s, share=%s, rss=%s"
+
+#define SS_TYPE_BEFORE 1
+#define SS_TYPE_AFTER 2
+#define SS_TYPE_DIFF 3
+
+/*
+ * XXX: this is pretty ugly,
+ * but avoids allocating buffers for the size string
+ */
+static void modperl_gtop_proc_mem_size_string(modperl_gtop_t *gtop, int type)
+{
+ int is_diff = (type == SS_TYPE_DIFF);
+ glibtop_proc_mem *pm = NULL;
+
+ if (!is_diff) {
+ pm = (type == SS_TYPE_BEFORE) ?
+ >op->before.proc_mem : >op->after.proc_mem;
+ }
+
+#define ss_call(item) \
+ modperl_gtop_size_string(is_diff ? \
+ modperl_gtop_diff(proc_mem.item) : pm->item, \
+ gtop->proc_mem_ss.item)
+
+ ss_call(size);
+ ss_call(vsize);
+ ss_call(resident);
+ ss_call(share);
+ ss_call(rss);
+#undef ss_call
+}
+
+void modperl_gtop_report_proc_mem(modperl_gtop_t *gtop,
+ char *when, const char *func, char *msg)
+{
+#define ss_item(item) gtop->proc_mem_ss.item
+
+ fprintf(stderr, "%s : %s %s: " ss_fmt "\n",
+ func, (msg ? msg : ""), when,
+ ss_item(size),
+ ss_item(vsize),
+ ss_item(resident),
+ ss_item(share),
+ ss_item(rss));
+
+#undef ss_item
+}
+
+void modperl_gtop_report_proc_mem_diff(modperl_gtop_t *gtop, const char *func, char *msg)
+{
+ modperl_gtop_proc_mem_size_string(gtop, SS_TYPE_DIFF);
+ modperl_gtop_report_proc_mem(gtop, "diff", func, msg);
+}
+
+void modperl_gtop_report_proc_mem_before(modperl_gtop_t *gtop, const char *func, char *msg)
+{
+ modperl_gtop_proc_mem_size_string(gtop, SS_TYPE_BEFORE);
+ modperl_gtop_report_proc_mem(gtop, "before", func, msg);
+}
+
+void modperl_gtop_report_proc_mem_after(modperl_gtop_t *gtop, const char *func, char *msg)
+{
+ modperl_gtop_proc_mem_size_string(gtop, SS_TYPE_AFTER);
+ modperl_gtop_report_proc_mem(gtop, "after", func, msg);
+}
+
+#endif /* MP_USE_GTOP */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_gtop.h b/2_0_13/src/modules/perl/modperl_gtop.h
new file mode 100644
index 0000000..61554de
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_gtop.h
@@ -0,0 +1,81 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_GTOP_H
+#define MODPERL_GTOP_H
+
+#ifndef MP_TRACE
+# undef MP_USE_GTOP
+#endif
+
+#ifdef MP_USE_GTOP
+/* prevent undef symbol errors (glibtop_error_vr) */
+#define __GLIBTOP_ERROR_H__
+#include <glibtop.h>
+#include <glibtop/open.h>
+#include <glibtop/close.h>
+#ifndef GTOP_2_5_PLUS
+#include <glibtop/xmalloc.h>
+#endif
+#include <glibtop/parameter.h>
+#include <glibtop/union.h>
+#include <glibtop/sysdeps.h>
+
+#define MP_GTOP_SSS 16
+
+typedef struct {
+ char size[MP_GTOP_SSS];
+ char vsize[MP_GTOP_SSS];
+ char resident[MP_GTOP_SSS];
+ char share[MP_GTOP_SSS];
+ char rss[MP_GTOP_SSS];
+} modperl_gtop_proc_mem_ss;
+
+typedef struct {
+ glibtop_union before;
+ glibtop_union after;
+ pid_t pid;
+ modperl_gtop_proc_mem_ss proc_mem_ss;
+} modperl_gtop_t;
+
+modperl_gtop_t *modperl_gtop_new(apr_pool_t *p);
+void modperl_gtop_get_proc_mem_before(modperl_gtop_t *gtop);
+void modperl_gtop_get_proc_mem_after(modperl_gtop_t *gtop);
+void modperl_gtop_report_proc_mem(modperl_gtop_t *gtop,
+ char *when, const char *func, char *msg);
+void modperl_gtop_report_proc_mem_diff(modperl_gtop_t *gtop, const char* func, char *msg);
+void modperl_gtop_report_proc_mem_before(modperl_gtop_t *gtop, const char* func, char *msg);
+void modperl_gtop_report_proc_mem_after(modperl_gtop_t *gtop, const char* func, char *msg);
+
+#define modperl_gtop_do_proc_mem_before(func, msg) \
+ modperl_gtop_get_proc_mem_before(scfg->gtop); \
+ modperl_gtop_report_proc_mem_before(scfg->gtop, func, msg)
+
+#define modperl_gtop_do_proc_mem_after(func, msg) \
+ modperl_gtop_get_proc_mem_after(scfg->gtop); \
+ modperl_gtop_report_proc_mem_after(scfg->gtop, func, msg); \
+ modperl_gtop_report_proc_mem_diff(scfg->gtop, func, msg)
+
+#endif /* MP_USE_GTOP */
+
+#endif /* MODPERL_GTOP_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_handler.c b/2_0_13/src/modules/perl/modperl_handler.c
new file mode 100644
index 0000000..fe935d7
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_handler.c
@@ -0,0 +1,642 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+modperl_handler_t *modperl_handler_new(apr_pool_t *p, const char *name)
+{
+ modperl_handler_t *handler =
+ (modperl_handler_t *)apr_pcalloc(p, sizeof(*handler));
+
+ switch (*name) {
+ case '+':
+ ++name;
+ MpHandlerAUTOLOAD_On(handler);
+ break;
+ case '-':
+ ++name;
+ /* XXX: currently a noop; should disable autoload of given handler
+ * if PerlOptions +AutoLoad is configured
+ * see: modperl_hash_handlers in modperl_mgv.c
+ */
+ MpHandlerAUTOLOAD_Off(handler);
+ break;
+ }
+
+ /* not necessary due to apr_pcalloc */
+ /* handler->cv = NULL; */
+ handler->name = name;
+ MP_TRACE_h(MP_FUNC, "new handler %s", handler->name);
+
+ return handler;
+}
+
+/* How anon-subs are handled:
+ * We have two ways anon-subs can be registered
+ * A) at startup from httpd.conf:
+ * PerlTransHandler 'sub { ... }'
+ * B) run-time perl code
+ * $r->push_handlers(PerlTransHandler => sub { .... });
+ * $s->push_handlers(PerlTransHandler => sub { .... });
+ *
+ * In the case of non-threaded perl, we just compile A or grab B and
+ * store it in the mod_perl struct and call it when it's used. No
+ * problems here
+ *
+ * In the case of threads, things get more complicated. we no longer
+ * can store the CV value of the compiled anon-sub, since when
+ * perl_clone is called each interpreter will have a different CV
+ * value. since we need to be able to have 1 entry for each anon-sub
+ * across all interpreters a different solution is needed. to remind
+ * in the case of named subs, we just store the name of the sub and
+ * look its corresponding CV when we need it.
+ *
+ * The used solution: each process has a global counter, which always
+ * grows. Every time a new anon-sub is encountered, a new ID is
+ * allocated from that process-global counter and that ID is stored in
+ * the mod_perl struct. The compiled CV is stored as
+ * $PL_modglobal{ANONSUB}{$id} = CV;
+ * when perl_clone is called, each clone will clone that CV value, but
+ * we will still be able to find it, since we stored it in the
+ * hash. so we retrieve the CV value, whatever it is and we run it.
+ *
+ * that explanation can be written and run in perl:
+ *
+ * use threads;
+ * our %h;
+ * $h{x} = eval 'sub { print qq[this is sub @_\n] }';
+ * $h{x}->("main");
+ * threads->new(sub { $h{x}->(threads->self->tid)});
+ *
+ * XXX: more nuances will follow
+ */
+
+void modperl_handler_anon_init(pTHX_ apr_pool_t *p)
+{
+ modperl_modglobal_key_t *gkey =
+ modperl_modglobal_lookup(aTHX_ "ANONSUB");
+ MP_TRACE_h(MP_FUNC, "init $PL_modglobal{ANONSUB} = []");
+ (void)MP_MODGLOBAL_STORE_HV(gkey);
+}
+
+/* allocate and populate the anon handler sub-struct */
+MP_INLINE modperl_mgv_t *modperl_handler_anon_next(pTHX_ apr_pool_t *p)
+{
+ /* re-use modperl_mgv_t entry which is otherwise is not used
+ * by anon handlers */
+ modperl_mgv_t *anon =
+ (modperl_mgv_t *)apr_pcalloc(p, sizeof(*anon));
+
+ anon->name = apr_psprintf(p, "anon%d", modperl_global_anon_cnt_next());
+ anon->len = strlen(anon->name);
+ PERL_HASH(anon->hash, anon->name, anon->len);
+
+ MP_TRACE_h(MP_FUNC, "new anon handler: '%s'", anon->name);
+ return anon;
+}
+
+MP_INLINE void modperl_handler_anon_add(pTHX_ modperl_mgv_t *anon, CV *cv)
+{
+ modperl_modglobal_key_t *gkey =
+ modperl_modglobal_lookup(aTHX_ "ANONSUB");
+ HE *he = MP_MODGLOBAL_FETCH(gkey);
+ HV *hv;
+
+ if (!(he && (hv = (HV*)HeVAL(he)))) {
+ Perl_croak(aTHX_ "modperl_handler_anon_add: "
+ "can't find ANONSUB top entry (get)");
+ }
+
+ SvREFCNT_inc(cv);
+ if (!(*hv_store(hv, anon->name, anon->len, (SV*)cv, anon->hash))) {
+ SvREFCNT_dec(cv);
+ Perl_croak(aTHX_ "hv_store of anonsub '%s' has failed!", anon->name);
+ }
+
+ MP_TRACE_h(MP_FUNC, "anonsub '%s' added", anon->name);
+}
+
+MP_INLINE CV *modperl_handler_anon_get(pTHX_ modperl_mgv_t *anon)
+{
+ modperl_modglobal_key_t *gkey =
+ modperl_modglobal_lookup(aTHX_ "ANONSUB");
+ HE *he = MP_MODGLOBAL_FETCH(gkey);
+ HV *hv;
+ SV *sv;
+
+ if (!(he && (hv = (HV*)HeVAL(he)))) {
+ Perl_croak(aTHX_ "modperl_handler_anon_get: "
+ "can't find ANONSUB top entry (get)");
+ }
+
+ if ((he = hv_fetch_he(hv, anon->name, anon->len, anon->hash))) {
+ sv = HeVAL(he);
+ MP_TRACE_h(MP_FUNC, "anonsub gets name '%s'", anon->name);
+ }
+ else {
+ Perl_croak(aTHX_ "can't find ANONSUB's '%s' entry", anon->name);
+ }
+
+ return (CV*)sv;
+}
+
+static
+modperl_handler_t *modperl_handler_new_anon(pTHX_ apr_pool_t *p, CV *cv)
+{
+ modperl_handler_t *handler =
+ (modperl_handler_t *)apr_pcalloc(p, sizeof(*handler));
+ MpHandlerPARSED_On(handler);
+ MpHandlerANON_On(handler);
+
+#ifdef USE_ITHREADS
+ handler->cv = NULL;
+ handler->name = NULL;
+ handler->mgv_obj = modperl_handler_anon_next(aTHX_ p);
+ modperl_handler_anon_add(aTHX_ handler->mgv_obj, cv);
+#else
+ /* it's safe to cache and later use the cv, since the same perl
+ * interpeter is always used */
+ SvREFCNT_inc((SV*)cv);
+ handler->cv = cv;
+ handler->name = NULL;
+
+ MP_TRACE_h(MP_FUNC, "new cached cv anon handler");
+#endif
+
+ return handler;
+}
+
+MP_INLINE
+const char *modperl_handler_name(modperl_handler_t *handler)
+{
+ /* a handler containing an anonymous sub doesn't have a normal sub
+ * name */
+ if (handler->name) {
+ return handler->name;
+ }
+ else {
+ /* anon sub stores the internal modperl name in mgv_obj */
+ return handler->mgv_obj ? handler->mgv_obj->name : "anonsub";
+ }
+}
+
+
+int modperl_handler_resolve(pTHX_ modperl_handler_t **handp,
+ apr_pool_t *p, server_rec *s)
+{
+ int duped=0;
+ modperl_handler_t *handler = *handp;
+
+#ifdef USE_ITHREADS
+ if (modperl_threaded_mpm() && p &&
+ !MpHandlerPARSED(handler) && !MpHandlerDYNAMIC(handler)) {
+ /*
+ * under threaded mpm we cannot update the handler structure
+ * at request time without locking, so just copy it
+ */
+ handler = *handp = modperl_handler_dup(p, handler);
+ duped = 1;
+ }
+#endif
+
+ MP_TRACE_h_do(MpHandler_dump_flags(handler,
+ modperl_handler_name(handler)));
+
+ if (!MpHandlerPARSED(handler)) {
+ apr_pool_t *rp = duped ? p : s->process->pconf;
+ MpHandlerAUTOLOAD_On(handler);
+
+ MP_TRACE_h(MP_FUNC,
+ "[%s] handler %s hasn't yet been resolved, "
+ "attempting to resolve using %s pool 0x%lx",
+ modperl_server_desc(s, p),
+ modperl_handler_name(handler),
+ duped ? "current" : "server conf",
+ (unsigned long)rp);
+
+ if (!modperl_mgv_resolve(aTHX_ handler, rp, handler->name, FALSE)) {
+ modperl_errsv_prepend(aTHX_
+ "failed to resolve handler `%s': ",
+ handler->name);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ return OK;
+}
+
+modperl_handler_t *modperl_handler_dup(apr_pool_t *p,
+ modperl_handler_t *h)
+{
+ MP_TRACE_h(MP_FUNC, "dup handler %s", modperl_handler_name(h));
+ return modperl_handler_new(p, h->name);
+}
+
+int modperl_handler_equal(modperl_handler_t *h1, modperl_handler_t *h2)
+{
+ if (h1->mgv_cv && h2->mgv_cv) {
+ return modperl_mgv_equal(h1->mgv_cv, h2->mgv_cv);
+ }
+ return strEQ(h1->name, h2->name);
+}
+
+MpAV *modperl_handler_array_merge(apr_pool_t *p, MpAV *base_a, MpAV *add_a)
+{
+ int i, j;
+ modperl_handler_t **base_h, **add_h;
+ MpAV *mrg_a;
+
+ if (!add_a) {
+ return base_a;
+ }
+
+ if (!base_a) {
+ return add_a;
+ }
+
+ mrg_a = apr_array_copy(p, base_a);
+
+ base_h = (modperl_handler_t **)base_a->elts;
+ add_h = (modperl_handler_t **)add_a->elts;
+
+ for (i=0; i<base_a->nelts; i++) {
+ for (j=0; j<add_a->nelts; j++) {
+ if (modperl_handler_equal(base_h[i], add_h[j])) {
+ MP_TRACE_d(MP_FUNC, "both base and new config contain %s",
+ add_h[j]->name);
+ }
+ else {
+ modperl_handler_array_push(mrg_a, add_h[j]);
+ MP_TRACE_d(MP_FUNC, "base does not contain %s",
+ add_h[j]->name);
+ }
+ }
+ }
+
+ return mrg_a;
+}
+
+void modperl_handler_make_args(pTHX_ AV **avp, ...)
+{
+ va_list args;
+
+ if (!*avp) {
+ *avp = newAV(); /* XXX: cache an intialized AV* per-request */
+ }
+
+ va_start(args, avp);
+
+ for (;;) {
+ char *classname = va_arg(args, char *);
+ void *ptr;
+ SV *sv;
+
+ if (classname == NULL) {
+ break;
+ }
+
+ ptr = va_arg(args, void *);
+
+ switch (*classname) {
+ case 'A':
+ if (strEQ(classname, "APR::Table")) {
+ sv = modperl_hash_tie(aTHX_ classname, (SV *)NULL, ptr);
+ break;
+ }
+ case 'I':
+ if (strEQ(classname, "IV")) {
+ sv = ptr ? newSViv(PTR2IV(ptr)) : &PL_sv_undef;
+ break;
+ }
+ case 'P':
+ if (strEQ(classname, "PV")) {
+ sv = ptr ? newSVpv((char *)ptr, 0) : &PL_sv_undef;
+ break;
+ }
+ case 'H':
+ if (strEQ(classname, "HV")) {
+ sv = newRV_noinc((SV*)ptr);
+ break;
+ }
+ default:
+ sv = modperl_ptr2obj(aTHX_ classname, ptr);
+ break;
+ }
+
+ av_push(*avp, sv);
+ }
+
+ va_end(args);
+}
+
+#define set_desc(dtype) \
+ if (desc) *desc = modperl_handler_desc_##dtype(idx)
+
+/* We should be able to use PERL_GET_CONTEXT here. The rcfg condition
+ * makes sure there is a request being processed. The action > GET part
+ * means it is a $r->set_handlers or $r->push_handlers operation. This
+ * can only happen if called by perl code.
+ */
+#define check_modify(dtype) \
+ if ((action > MP_HANDLER_ACTION_GET) && rcfg) { \
+ dTHXa(PERL_GET_CONTEXT); \
+ MP_ASSERT(aTHX+0); \
+ Perl_croak(aTHX_ "too late to modify %s handlers", \
+ modperl_handler_desc_##dtype(idx)); \
+ }
+
+/*
+ * generic function to lookup handlers for use in modperl_callback(),
+ * $r->{push,set,get}_handlers, $s->{push,set,get}_handlers
+ * $s->push/set at startup time are the same as configuring Perl*Handlers
+ * $r->push/set at request time will create entries in r->request_config
+ * push will first merge with configured handlers, unless an entry
+ * in r->request_config already exists. in this case, push or set has
+ * already been called for the given handler,
+ * r->request_config entries then override those in r->per_dir_config
+ */
+
+MpAV **modperl_handler_lookup_handlers(modperl_config_dir_t *dcfg,
+ modperl_config_srv_t *scfg,
+ modperl_config_req_t *rcfg,
+ apr_pool_t *p,
+ int type, int idx,
+ modperl_handler_action_e action,
+ const char **desc)
+{
+ MpAV **avp = NULL, **ravp = NULL;
+
+ switch (type) {
+ case MP_HANDLER_TYPE_PER_DIR:
+ avp = &dcfg->handlers_per_dir[idx];
+ if (rcfg) {
+ ravp = &rcfg->handlers_per_dir[idx];
+ }
+ set_desc(per_dir);
+ break;
+ case MP_HANDLER_TYPE_PER_SRV:
+ avp = &scfg->handlers_per_srv[idx];
+ if (rcfg) {
+ ravp = &rcfg->handlers_per_srv[idx];
+ }
+ set_desc(per_srv);
+ break;
+ case MP_HANDLER_TYPE_PRE_CONNECTION:
+ avp = &scfg->handlers_pre_connection[idx];
+ check_modify(pre_connection);
+ set_desc(pre_connection);
+ break;
+ case MP_HANDLER_TYPE_CONNECTION:
+ avp = &scfg->handlers_connection[idx];
+ check_modify(connection);
+ set_desc(connection);
+ break;
+ case MP_HANDLER_TYPE_FILES:
+ avp = &scfg->handlers_files[idx];
+ check_modify(files);
+ set_desc(files);
+ break;
+ case MP_HANDLER_TYPE_PROCESS:
+ avp = &scfg->handlers_process[idx];
+ check_modify(files);
+ set_desc(process);
+ break;
+ };
+
+ if (!avp) {
+ /* should never happen */
+#if 0
+ fprintf(stderr, "PANIC: no such handler type: %d\n", type);
+#endif
+ return NULL;
+ }
+
+ switch (action) {
+ case MP_HANDLER_ACTION_GET:
+ /* just a lookup */
+ break;
+ case MP_HANDLER_ACTION_PUSH:
+ if (ravp) {
+ if (!*ravp) {
+ if (*avp) {
+ /* merge with existing configured handlers */
+ *ravp = apr_array_copy(p, *avp);
+ }
+ else {
+ /* no request handlers have been previously pushed or set */
+ *ravp = modperl_handler_array_new(p);
+ }
+ }
+ }
+ else if (!*avp) {
+ /* directly modify the configuration at startup time */
+ *avp = modperl_handler_array_new(p);
+ }
+ break;
+ case MP_HANDLER_ACTION_SET:
+ if (ravp) {
+ if (*ravp) {
+ /* wipe out existing pushed/set request handlers */
+ (*ravp)->nelts = 0;
+ }
+ else {
+ /* no request handlers have been previously pushed or set */
+ *ravp = modperl_handler_array_new(p);
+ }
+ }
+ else if (*avp) {
+ /* wipe out existing configuration, only at startup time */
+ (*avp)->nelts = 0;
+ }
+ else {
+ /* no configured handlers for this phase */
+ *avp = modperl_handler_array_new(p);
+ }
+ break;
+ }
+
+ return (ravp && *ravp) ? ravp : avp;
+}
+
+MpAV **modperl_handler_get_handlers(request_rec *r, conn_rec *c, server_rec *s,
+ apr_pool_t *p, const char *name,
+ modperl_handler_action_e action)
+{
+ MP_dSCFG(s);
+ MP_dDCFG;
+ MP_dRCFG;
+
+ int idx, type;
+
+ if (!r) {
+ /* so $s->{push,set}_handlers can configured request-time handlers */
+ dcfg = modperl_config_dir_get_defaults(s);
+ }
+
+ if ((idx = modperl_handler_lookup(name, &type)) == DECLINED) {
+ return FALSE;
+ }
+
+ return modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p,
+ type, idx,
+ action, NULL);
+}
+
+modperl_handler_t *modperl_handler_new_from_sv(pTHX_ apr_pool_t *p, SV *sv)
+{
+ char *name = NULL;
+ GV *gv;
+
+ if (SvROK(sv)) {
+ sv = SvRV(sv);
+ }
+
+ switch (SvTYPE(sv)) {
+ case SVt_PV:
+ name = SvPVX(sv);
+ return modperl_handler_new(p, apr_pstrdup(p, name));
+ break;
+ case SVt_PVCV:
+ if (CvANON((CV*)sv)) {
+ return modperl_handler_new_anon(aTHX_ p, (CV*)sv);
+ }
+ if (!(gv = CvGV((CV*)sv))) {
+ Perl_croak(aTHX_ "can't resolve the code reference");
+ }
+ name = apr_pstrcat(p, HvNAME(GvSTASH(gv)), "::", GvNAME(gv), NULL);
+ return modperl_handler_new(p, name);
+ default:
+ break;
+ };
+
+ return NULL;
+}
+
+int modperl_handler_push_handlers(pTHX_ apr_pool_t *p,
+ MpAV *handlers, SV *sv)
+{
+ modperl_handler_t *handler = modperl_handler_new_from_sv(aTHX_ p, sv);
+
+ if (handler) {
+ modperl_handler_array_push(handlers, handler);
+ return TRUE;
+ }
+
+ MP_TRACE_h(MP_FUNC, "unable to push_handler 0x%lx",
+ (unsigned long)sv);
+
+ return FALSE;
+}
+
+/* convert array header of modperl_handlers_t's to AV ref of CV refs */
+SV *modperl_handler_perl_get_handlers(pTHX_ MpAV **handp, apr_pool_t *p)
+{
+ AV *av = newAV();
+ int i;
+ modperl_handler_t **handlers;
+
+ if (!(handp && *handp)) {
+ return &PL_sv_undef;
+ }
+
+ av_extend(av, (*handp)->nelts - 1);
+
+ handlers = (modperl_handler_t **)(*handp)->elts;
+
+ for (i=0; i<(*handp)->nelts; i++) {
+ modperl_handler_t *handler = NULL;
+ GV *gv;
+
+ if (MpHandlerPARSED(handlers[i])) {
+ handler = handlers[i];
+ }
+ else {
+#ifdef USE_ITHREADS
+ if (!MpHandlerDYNAMIC(handlers[i])) {
+ handler = modperl_handler_dup(p, handlers[i]);
+ }
+#endif
+ if (!handler) {
+ handler = handlers[i];
+ }
+
+ if (!modperl_mgv_resolve(aTHX_ handler, p, handler->name, TRUE)) {
+ MP_TRACE_h(MP_FUNC, "failed to resolve handler %s",
+ handler->name);
+ }
+
+ }
+
+ if (handler->mgv_cv) {
+ if ((gv = modperl_mgv_lookup(aTHX_ handler->mgv_cv))) {
+ CV *cv = modperl_mgv_cv(gv);
+ av_push(av, newRV_inc((SV*)cv));
+ }
+ }
+ else {
+ av_push(av, newSVpv(handler->name, 0));
+ }
+ }
+
+ return newRV_noinc((SV*)av);
+}
+
+#define push_sv_handler \
+ if ((modperl_handler_push_handlers(aTHX_ p, *handlers, sv))) { \
+ MpHandlerDYNAMIC_On(modperl_handler_array_last(*handlers)); \
+ }
+
+/* allow push/set of single cv ref or array ref of cv refs */
+int modperl_handler_perl_add_handlers(pTHX_
+ request_rec *r,
+ conn_rec *c,
+ server_rec *s,
+ apr_pool_t *p,
+ const char *name,
+ SV *sv,
+ modperl_handler_action_e action)
+{
+ I32 i;
+ AV *av = (AV *)NULL;
+ MpAV **handlers =
+ modperl_handler_get_handlers(r, c, s,
+ p, name, action);
+
+ if (!(handlers && *handlers)) {
+ return FALSE;
+ }
+
+ if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV)) {
+ av = (AV*)SvRV(sv);
+
+ for (i=0; i <= AvFILL(av); i++) {
+ sv = *av_fetch(av, i, FALSE);
+ push_sv_handler;
+ }
+ }
+ else {
+ push_sv_handler;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_handler.h b/2_0_13/src/modules/perl/modperl_handler.h
new file mode 100644
index 0000000..af3a8dd
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_handler.h
@@ -0,0 +1,94 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_HANDLER_H
+#define MODPERL_HANDLER_H
+
+typedef enum {
+ MP_HANDLER_ACTION_GET,
+ MP_HANDLER_ACTION_PUSH,
+ MP_HANDLER_ACTION_SET
+} modperl_handler_action_e;
+
+void modperl_handler_anon_init(pTHX_ apr_pool_t *p);
+MP_INLINE modperl_mgv_t *modperl_handler_anon_next(pTHX_ apr_pool_t *p);
+MP_INLINE void modperl_handler_anon_add(pTHX_ modperl_mgv_t *anon, CV *cv);
+MP_INLINE CV *modperl_handler_anon_get(pTHX_ modperl_mgv_t *anon);
+
+#define modperl_handler_array_new(p) \
+apr_array_make(p, 1, sizeof(modperl_handler_t *))
+
+#define modperl_handler_array_push(handlers, h) \
+*(modperl_handler_t **)apr_array_push(handlers) = h
+
+#define modperl_handler_array_item(handlers, idx) \
+((modperl_handler_t **)(handlers)->elts)[idx]
+
+#define modperl_handler_array_last(handlers) \
+modperl_handler_array_item(handlers, ((handlers)->nelts - 1))
+
+modperl_handler_t *modperl_handler_new(apr_pool_t *p, const char *name);
+
+modperl_handler_t *modperl_handler_new_from_sv(pTHX_ apr_pool_t *p, SV *sv);
+
+MP_INLINE const char *modperl_handler_name(modperl_handler_t *handler);
+
+int modperl_handler_resolve(pTHX_ modperl_handler_t **handp,
+ apr_pool_t *p, server_rec *s);
+
+modperl_handler_t *modperl_handler_dup(apr_pool_t *p,
+ modperl_handler_t *h);
+
+int modperl_handler_equal(modperl_handler_t *h1, modperl_handler_t *h2);
+
+MpAV *modperl_handler_array_merge(apr_pool_t *p, MpAV *base_a, MpAV *add_a);
+
+void modperl_handler_make_args(pTHX_ AV **avp, ...);
+
+MpAV **modperl_handler_lookup_handlers(modperl_config_dir_t *dcfg,
+ modperl_config_srv_t *scfg,
+ modperl_config_req_t *rcfg,
+ apr_pool_t *p,
+ int type, int idx,
+ modperl_handler_action_e action,
+ const char **desc);
+
+MpAV **modperl_handler_get_handlers(request_rec *r, conn_rec *c,server_rec *s,
+ apr_pool_t *p, const char *name,
+ modperl_handler_action_e action);
+
+int modperl_handler_push_handlers(pTHX_ apr_pool_t *p,
+ MpAV *handlers, SV *sv);
+
+SV *modperl_handler_perl_get_handlers(pTHX_ MpAV **handp, apr_pool_t *p);
+
+int modperl_handler_perl_add_handlers(pTHX_
+ request_rec *r,
+ conn_rec *c,
+ server_rec *s,
+ apr_pool_t *p,
+ const char *name,
+ SV *sv,
+ modperl_handler_action_e action);
+
+#endif /* MODPERL_HANDLER_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_interp.c b/2_0_13/src/modules/perl/modperl_interp.c
new file mode 100644
index 0000000..35f5cea
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_interp.c
@@ -0,0 +1,565 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/*
+ * XXX: this is not the most efficent interpreter pool implementation
+ * but it will do for proof-of-concept
+ */
+
+#ifdef USE_ITHREADS
+
+void modperl_interp_clone_init(modperl_interp_t *interp)
+{
+ dTHXa(interp->perl);
+
+ MpInterpCLONED_On(interp);
+
+ MP_ASSERT_CONTEXT(aTHX);
+
+ /* clear @DynaLoader::dl_librefs so we only dlclose() those
+ * which are opened by the clone
+ */
+ modperl_xs_dl_handles_clear(aTHX);
+}
+
+modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip,
+ PerlInterpreter *perl)
+{
+ UV clone_flags = CLONEf_KEEP_PTR_TABLE;
+ modperl_interp_t *interp =
+ (modperl_interp_t *)malloc(sizeof(*interp));
+
+ memset(interp, '\0', sizeof(*interp));
+
+ interp->mip = mip;
+ interp->refcnt = 0;
+
+ if (perl) {
+#ifdef MP_USE_GTOP
+ MP_dSCFG(mip->server);
+ MP_TRACE_m_do(
+ modperl_gtop_do_proc_mem_before(MP_FUNC, "perl_clone");
+ );
+#endif
+
+#if defined(WIN32) && defined(CLONEf_CLONE_HOST)
+ clone_flags |= CLONEf_CLONE_HOST;
+#endif
+
+ PERL_SET_CONTEXT(perl);
+
+ interp->perl = perl_clone(perl, clone_flags);
+
+ MP_ASSERT_CONTEXT(interp->perl);
+
+ {
+ PTR_TBL_t *source = modperl_module_config_table_get(perl, FALSE);
+ if (source) {
+ PTR_TBL_t *table = modperl_svptr_table_clone(interp->perl,
+ perl,
+ source);
+
+ modperl_module_config_table_set(interp->perl, table);
+ }
+ }
+
+ /*
+ * we keep the PL_ptr_table past perl_clone so it can be used
+ * within modperl_svptr_table_clone. Perl_sv_dup() uses it.
+ * Don't confuse our svptr_table with Perl's ptr_table. They
+ * are different things, although they use the same type.
+ */
+ if ((clone_flags & CLONEf_KEEP_PTR_TABLE)) {
+ dTHXa(interp->perl);
+ ptr_table_free(PL_ptr_table);
+ PL_ptr_table = NULL;
+ }
+
+ modperl_interp_clone_init(interp);
+
+ PERL_SET_CONTEXT(perl);
+
+#ifdef MP_USE_GTOP
+ MP_TRACE_m_do(
+ modperl_gtop_do_proc_mem_after(MP_FUNC, "perl_clone");
+ );
+#endif
+ }
+
+ MP_TRACE_i(MP_FUNC, "0x%lx / perl: 0x%lx / parent perl: 0x%lx",
+ (unsigned long)interp, (unsigned long)interp->perl,
+ (unsigned long)perl);
+
+ return interp;
+}
+
+void modperl_interp_destroy(modperl_interp_t *interp)
+{
+ void **handles;
+ dTHXa(interp->perl);
+
+ PERL_SET_CONTEXT(interp->perl);
+
+ MP_TRACE_i(MP_FUNC, "interp == 0x%lx / perl: 0x%lx",
+ (unsigned long)interp, (unsigned long)interp->perl);
+
+ if (MpInterpIN_USE(interp)) {
+ MP_TRACE_i(MP_FUNC, "*error - still in use!*");
+ }
+
+ handles = modperl_xs_dl_handles_get(aTHX);
+
+ modperl_perl_destruct(interp->perl);
+
+ modperl_xs_dl_handles_close(handles);
+
+ free(interp);
+}
+
+apr_status_t modperl_interp_cleanup(void *data)
+{
+ modperl_interp_destroy((modperl_interp_t *)data);
+ return APR_SUCCESS;
+}
+
+modperl_interp_t *modperl_interp_get(server_rec *s)
+{
+ MP_dSCFG(s);
+ modperl_interp_t *interp = NULL;
+ modperl_interp_pool_t *mip = scfg->mip;
+ modperl_list_t *head;
+
+ head = modperl_tipool_pop(mip->tipool);
+ interp = (modperl_interp_t *)head->data;
+
+ MP_TRACE_i(MP_FUNC, "head == 0x%lx, parent == 0x%lx",
+ (unsigned long)head, (unsigned long)mip->parent);
+
+ MP_TRACE_i(MP_FUNC, "selected 0x%lx (perl==0x%lx)",
+ (unsigned long)interp,
+ (unsigned long)interp->perl);
+
+#ifdef MP_TRACE
+ interp->tid = MP_TIDF;
+ MP_TRACE_i(MP_FUNC, "thread == 0x%lx", interp->tid);
+#endif
+
+ MpInterpIN_USE_On(interp);
+
+ return interp;
+}
+
+apr_status_t modperl_interp_pool_destroy(void *data)
+{
+ modperl_interp_pool_t *mip = (modperl_interp_pool_t *)data;
+
+ if (mip->tipool) {
+ modperl_tipool_destroy(mip->tipool);
+ mip->tipool = NULL;
+ }
+
+ if (MpInterpBASE(mip->parent)) {
+ /* multiple mips might share the same parent
+ * make sure its only destroyed once
+ */
+ MP_TRACE_i(MP_FUNC, "parent == 0x%lx",
+ (unsigned long)mip->parent);
+
+ modperl_interp_destroy(mip->parent);
+ }
+
+ return APR_SUCCESS;
+}
+
+static void *interp_pool_grow(modperl_tipool_t *tipool, void *data)
+{
+ modperl_interp_pool_t *mip = (modperl_interp_pool_t *)data;
+ MP_TRACE_i(MP_FUNC, "adding new interpreter to the pool");
+ return (void *)modperl_interp_new(mip, mip->parent->perl);
+}
+
+static void interp_pool_shrink(modperl_tipool_t *tipool, void *data,
+ void *item)
+{
+ modperl_interp_destroy((modperl_interp_t *)item);
+}
+
+static void interp_pool_dump(modperl_tipool_t *tipool, void *data,
+ modperl_list_t *listp)
+{
+ while (listp) {
+ modperl_interp_t *interp = (modperl_interp_t *)listp->data;
+ MP_TRACE_i(MP_FUNC, "listp==0x%lx, interp==0x%lx, requests=%d",
+ (unsigned long)listp, (unsigned long)interp,
+ interp->num_requests);
+ listp = listp->next;
+ }
+}
+
+static modperl_tipool_vtbl_t interp_pool_func = {
+ interp_pool_grow,
+ interp_pool_grow,
+ interp_pool_shrink,
+ interp_pool_shrink,
+ interp_pool_dump,
+};
+
+void modperl_interp_init(server_rec *s, apr_pool_t *p,
+ PerlInterpreter *perl)
+{
+ apr_pool_t *server_pool = modperl_server_pool();
+ pTHX;
+ MP_dSCFG(s);
+ modperl_interp_pool_t *mip =
+ (modperl_interp_pool_t *)apr_pcalloc(p, sizeof(*mip));
+
+ MP_TRACE_i(MP_FUNC, "server=%s", modperl_server_desc(s, p));
+
+ if (modperl_threaded_mpm()) {
+ mip->tipool = modperl_tipool_new(p, scfg->interp_pool_cfg,
+ &interp_pool_func, mip);
+ }
+
+ mip->server = s;
+ mip->parent = modperl_interp_new(mip, NULL);
+ aTHX = mip->parent->perl = perl;
+
+ /* this happens post-config in mod_perl.c:modperl_init_clones() */
+ /* modperl_tipool_init(tipool); */
+
+ apr_pool_cleanup_register(server_pool, (void*)mip,
+ modperl_interp_pool_destroy,
+ apr_pool_cleanup_null);
+
+ scfg->mip = mip;
+}
+
+apr_status_t modperl_interp_unselect(void *data)
+{
+ modperl_interp_t *interp = (modperl_interp_t *)data;
+ modperl_interp_pool_t *mip = interp->mip;
+
+ MP_ASSERT(interp && MpInterpIN_USE(interp) && interp->refcnt > 0);
+ MP_TRACE_i(MP_FUNC, "unselect(interp=%pp): refcnt=%d",
+ interp, interp->refcnt);
+
+ --interp->refcnt;
+
+ if (interp->refcnt > 0) {
+ MP_TRACE_i(MP_FUNC, "interp=0x%lx, refcnt=%d -- interp still in use",
+ (unsigned long)interp, interp->refcnt);
+ return APR_SUCCESS;
+ }
+
+ if (!MpInterpIN_USE(interp)){
+ MP_TRACE_i(MP_FUNC, "interp=0x%pp, refcnt=%d -- interp already not in use",
+ interp, interp->refcnt);
+ return APR_SUCCESS;
+ }
+
+ MpInterpIN_USE_Off(interp);
+
+ modperl_thx_interp_set(interp->perl, NULL);
+#ifdef MP_DEBUG
+ PERL_SET_CONTEXT(NULL);
+#endif
+
+ if (interp == mip->parent) {
+ MP_TRACE_i(MP_FUNC, "parent interp=%pp freed", interp);
+ }
+ else {
+ interp->ccfg->interp = NULL;
+ modperl_tipool_putback_data(mip->tipool, data, interp->num_requests);
+ MP_TRACE_i(MP_FUNC, "interp=%pp freed, tipool(size=%ld, in_use=%ld)",
+ interp, mip->tipool->size, mip->tipool->in_use);
+ }
+
+ return APR_SUCCESS;
+}
+
+/* XXX:
+ * interp is marked as in_use for the scope of the pool it is
+ * stashed in. this is done to avoid the tipool->tlock whenever
+ * possible. neither approach is ideal.
+ */
+#define MP_INTERP_KEY "MODPERL_INTERP"
+
+#define get_interp(p) \
+ (void)apr_pool_userdata_get((void **)&interp, MP_INTERP_KEY, p)
+
+#define set_interp(p) \
+ (void)apr_pool_userdata_set((void *)interp, MP_INTERP_KEY, \
+ modperl_interp_unselect, \
+ p)
+
+modperl_interp_t *modperl_interp_pool_get(apr_pool_t *p)
+{
+ modperl_interp_t *interp = NULL;
+ get_interp(p);
+ return interp;
+}
+
+void modperl_interp_pool_set(apr_pool_t *p,
+ modperl_interp_t *interp)
+{
+ (void)apr_pool_userdata_set((void *)interp, MP_INTERP_KEY, NULL, p);
+}
+
+/*
+ * used in the case where we don't have a request_rec or conn_rec,
+ * such as for directive handlers per-{dir,srv} create and merge.
+ * "request time pool" is most likely a request_rec->pool.
+ */
+modperl_interp_t *modperl_interp_pool_select(apr_pool_t *p,
+ server_rec *s)
+{
+ int is_startup = (p == s->process->pconf);
+ modperl_interp_t *interp = NULL;
+
+ if (is_startup) {
+ MP_dSCFG(s);
+ if (scfg) {
+ MP_TRACE_i(MP_FUNC, "using parent interpreter at startup");
+
+ if (!scfg->mip) {
+ /* we get here if directive handlers are invoked
+ * before server merge.
+ */
+ modperl_init_vhost(s, p, NULL);
+ if (!scfg->mip) {
+ /* FIXME: We get here if global "server_rec" == s, scfg->mip
+ * is not created then. I'm not sure if that's bug or
+ * bad/good design decicision. For now just return NULL.
+ */
+ return NULL;
+ }
+ }
+
+ interp = scfg->mip->parent;
+ }
+ else {
+ if (!(interp = modperl_interp_pool_get(p))) {
+ interp = modperl_interp_get(s);
+ modperl_interp_pool_set(p, interp);
+
+ MP_TRACE_i(MP_FUNC, "set interp %pp in pconf pool %pp",
+ interp, p);
+ }
+ else {
+ MP_TRACE_i(MP_FUNC, "found interp %pp in pconf pool %pp",
+ interp, p);
+ }
+ }
+
+ MpInterpIN_USE_On(interp);
+ interp->refcnt++;
+ /* set context (THX) for this thread */
+ PERL_SET_CONTEXT(interp->perl);
+ /* let the perl interpreter point back to its interp */
+ modperl_thx_interp_set(interp->perl, interp);
+
+ return interp;
+ }
+ else {
+ request_rec *r;
+ apr_pool_userdata_get((void **)&r, "MODPERL_R", p);
+ MP_ASSERT(r);
+ MP_TRACE_i(MP_FUNC, "found userdata MODPERL_R in pool %#lx as %lx",
+ (unsigned long)r->pool, (unsigned long)r);
+ return modperl_interp_select(r, NULL, NULL);
+ }
+}
+
+modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c,
+ server_rec *s)
+{
+ MP_dSCFG((r ? s=r->server : c ? s=c->base_server : s));
+ MP_dDCFG;
+ modperl_config_con_t *ccfg;
+ const char *desc = NULL;
+ modperl_interp_t *interp = NULL;
+ apr_pool_t *p = NULL;
+
+ /* What does the following condition mean?
+ * (r || c): if true we are at runtime. There is some kind of request
+ * being processed.
+ * threaded_mpm: self-explanatory
+ *
+ * Thus, it is true if we are either at initialization time or at runtime
+ * but with prefork-MPM. */
+ if (!((r || c) && modperl_threaded_mpm())) {
+ interp = scfg->mip->parent;
+ MpInterpIN_USE_On(interp);
+ interp->refcnt++;
+ /* XXX: if no VirtualHosts w/ PerlOptions +Parent we can skip this */
+ PERL_SET_CONTEXT(interp->perl);
+ /* let the perl interpreter point back to its interp */
+ modperl_thx_interp_set(interp->perl, interp);
+
+ MP_TRACE_i(MP_FUNC,
+ "using parent 0x%pp (perl=0x%pp) for %s:%d refcnt set to %d",
+ interp, interp->perl, s->server_hostname, s->port,
+ interp->refcnt);
+ return interp;
+ }
+
+ if(!c) c = r->connection;
+ ccfg = modperl_config_con_get(c);
+
+ if (ccfg && ccfg->interp) {
+ ccfg->interp->refcnt++;
+
+ MP_TRACE_i(MP_FUNC,
+ "found interp 0x%lx in con config, refcnt incremented to %d",
+ (unsigned long)ccfg->interp, ccfg->interp->refcnt);
+ /* set context (THX) for this thread */
+ PERL_SET_CONTEXT(ccfg->interp->perl);
+ /* modperl_thx_interp_set() is not called here because the interp
+ * already belongs to the perl interpreter
+ */
+ return ccfg->interp;
+ }
+
+ MP_TRACE_i(MP_FUNC,
+ "fetching interp for %s:%d", s->server_hostname, s->port);
+ interp = modperl_interp_get(s);
+ MP_TRACE_i(MP_FUNC, " --> got %pp (perl=%pp)", interp, interp->perl);
+ ++interp->num_requests; /* should only get here once per request */
+ interp->refcnt = 1;
+
+ /* set context (THX) for this thread */
+ PERL_SET_CONTEXT(interp->perl);
+ /* let the perl interpreter point back to its interp */
+ modperl_thx_interp_set(interp->perl, interp);
+
+ /* make sure ccfg is initialized */
+ modperl_config_con_init(c, ccfg);
+ ccfg->interp = interp;
+ interp->ccfg = ccfg;
+
+ MP_TRACE_i(MP_FUNC,
+ "pulled interp %pp (perl=%pp) from mip, num_requests is %d",
+ interp, interp->perl, interp->num_requests);
+
+ return interp;
+}
+
+/* currently up to the caller if mip needs locking */
+void modperl_interp_mip_walk(PerlInterpreter *current_perl,
+ PerlInterpreter *parent_perl,
+ modperl_interp_pool_t *mip,
+ modperl_interp_mip_walker_t walker,
+ void *data)
+{
+ modperl_list_t *head = mip->tipool ? mip->tipool->idle : NULL;
+
+ if (!current_perl) {
+ current_perl = PERL_GET_CONTEXT;
+ }
+
+ if (parent_perl) {
+ PERL_SET_CONTEXT(parent_perl);
+ walker(parent_perl, mip, data);
+ }
+
+ while (head) {
+ PerlInterpreter *perl = ((modperl_interp_t *)head->data)->perl;
+ PERL_SET_CONTEXT(perl);
+ walker(perl, mip, data);
+ head = head->next;
+ }
+
+ PERL_SET_CONTEXT(current_perl);
+}
+
+void modperl_interp_mip_walk_servers(PerlInterpreter *current_perl,
+ server_rec *base_server,
+ modperl_interp_mip_walker_t walker,
+ void *data)
+{
+ server_rec *s = base_server->next;
+ modperl_config_srv_t *base_scfg = modperl_config_srv_get(base_server);
+ PerlInterpreter *base_perl = base_scfg->mip->parent->perl;
+
+ modperl_interp_mip_walk(current_perl, base_perl,
+ base_scfg->mip, walker, data);
+
+ while (s) {
+ MP_dSCFG(s);
+ PerlInterpreter *perl = scfg->mip->parent->perl;
+ modperl_interp_pool_t *mip = scfg->mip;
+
+ /* skip vhosts who share parent perl */
+ if (perl == base_perl) {
+ perl = NULL;
+ }
+
+ /* skip vhosts who share parent mip */
+ if (scfg->mip == base_scfg->mip) {
+ mip = NULL;
+ }
+
+ if (perl || mip) {
+ modperl_interp_mip_walk(current_perl, perl,
+ mip, walker, data);
+ }
+
+ s = s->next;
+ }
+}
+
+#define MP_THX_INTERP_KEY "modperl2::thx_interp_key"
+modperl_interp_t *modperl_thx_interp_get(pTHX)
+{
+ modperl_interp_t *interp;
+ SV **svp = hv_fetch(PL_modglobal, MP_THX_INTERP_KEY,
+ strlen(MP_THX_INTERP_KEY), 0);
+ if (!svp) return NULL;
+ interp = INT2PTR(modperl_interp_t *, SvIV(*svp));
+ return interp;
+}
+
+void modperl_thx_interp_set(pTHX_ modperl_interp_t *interp)
+{
+ (void)hv_store(PL_modglobal, MP_THX_INTERP_KEY, strlen(MP_THX_INTERP_KEY),
+ newSViv(PTR2IV(interp)), 0);
+ return;
+}
+
+#else
+
+void modperl_interp_init(server_rec *s, apr_pool_t *p,
+ PerlInterpreter *perl)
+{
+ MP_dSCFG(s);
+ scfg->perl = perl;
+}
+
+apr_status_t modperl_interp_cleanup(void *data)
+{
+ return APR_SUCCESS;
+}
+
+#endif /* USE_ITHREADS */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_interp.h b/2_0_13/src/modules/perl/modperl_interp.h
new file mode 100644
index 0000000..f3f4037
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_interp.h
@@ -0,0 +1,158 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_INTERP_H
+#define MODPERL_INTERP_H
+
+void modperl_interp_init(server_rec *s, apr_pool_t *p,
+ PerlInterpreter *perl);
+
+apr_status_t modperl_interp_cleanup(void *data);
+
+#ifdef USE_ITHREADS
+
+modperl_interp_t *modperl_thx_interp_get(PerlInterpreter *thx);
+void modperl_thx_interp_set(PerlInterpreter *thx, modperl_interp_t *interp);
+
+void modperl_interp_clone_init(modperl_interp_t *interp);
+
+modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip,
+ PerlInterpreter *perl);
+
+void modperl_interp_destroy(modperl_interp_t *interp);
+
+modperl_interp_t *modperl_interp_get(server_rec *s);
+
+apr_status_t modperl_interp_unselect(void *data);
+
+modperl_interp_t *modperl_interp_pool_get(apr_pool_t *p);
+
+void modperl_interp_pool_set(apr_pool_t *p,
+ modperl_interp_t *interp);
+
+modperl_interp_t *modperl_interp_pool_select(apr_pool_t *p,
+ server_rec *s);
+
+modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c,
+ server_rec *s);
+
+#define MP_dINTERP pTHX; modperl_interp_t *interp = NULL
+
+#define MP_INTERPa(r, c, s) \
+ MP_TRACE_i(MP_FUNC, "selecting interp: r=%pp, c=%pp, s=%pp", \
+ (r), (c), (s)); \
+ interp = modperl_interp_select((r), (c), (s)); \
+ if (interp) { \
+ MP_TRACE_i(MP_FUNC, " --> got (0x%pp)->refcnt=%d, perl=%pp", \
+ interp, interp->refcnt, interp->perl); \
+ aTHX = interp->perl; \
+ } \
+ else { \
+ aTHX = NULL; \
+ MP_TRACE_i(MP_FUNC, " --> failed"); \
+ } \
+ NOOP
+
+#define MP_dINTERPa(r, c, s) \
+ MP_dINTERP; \
+ MP_INTERPa((r), (c), (s))
+
+#define MP_INTERP_POOLa(p, s) \
+ MP_TRACE_i(MP_FUNC, "selecting interp: p=%pp, s=%pp", (p), (s)); \
+ interp = modperl_interp_pool_select((p), (s)); \
+ if (interp) { \
+ MP_TRACE_i(MP_FUNC, " --> got (0x%pp)->refcnt=%d", \
+ interp, interp->refcnt); \
+ aTHX = interp->perl; \
+ } \
+ else { \
+ aTHX = NULL; \
+ MP_TRACE_i(MP_FUNC, " --> failed"); \
+ } \
+ NOOP
+
+#define MP_dINTERP_POOLa(p, s) \
+ MP_dINTERP; \
+ MP_INTERP_POOLa((p), (s))
+
+#ifdef MP_DEBUG
+#define MP_INTERP_PUTBACK(interp, thx) \
+ MP_TRACE_i(MP_FUNC, "unselecting interp: (0x%pp)->refcnt=%ld", \
+ (interp), (interp)->refcnt); \
+ modperl_interp_unselect(interp); \
+ interp = NULL; \
+ if( thx ) thx = NULL
+#else /* MP_DEBUG */
+#define MP_INTERP_PUTBACK(interp, thx) \
+ modperl_interp_unselect(interp)
+#endif
+
+#define MP_INTERP_REFCNT_inc(interp) (interp)->refcnt++
+
+#define MP_INTERP_REFCNT_dec(interp) MP_INTERP_PUTBACK(interp, NULL)
+
+#define MP_HAS_INTERP(interp) (interp != NULL)
+
+#define MP_aTHX aTHX
+
+apr_status_t modperl_interp_pool_destroy(void *data);
+
+typedef apr_status_t (*modperl_interp_mip_walker_t)(pTHX_
+ modperl_interp_pool_t *mip,
+ void *data);
+
+void modperl_interp_mip_walk(PerlInterpreter *current_perl,
+ PerlInterpreter *parent_perl,
+ modperl_interp_pool_t *mip,
+ modperl_interp_mip_walker_t walker,
+ void *data);
+
+void modperl_interp_mip_walk_servers(PerlInterpreter *current_perl,
+ server_rec *base_server,
+ modperl_interp_mip_walker_t walker,
+ void *data);
+#else
+
+#define MP_dINTERP dNOOP
+
+#define MP_INTERPa(r, c, s) NOOP
+
+#define MP_dINTERPa(r, c, s) NOOP
+
+#define MP_INTERP_POOLa(p, s) NOOP
+
+#define MP_dINTERP_POOLa(p, s) NOOP
+
+#define MP_INTERP_PUTBACK(interp, thx) NOOP
+
+#define MP_INTERP_REFCNT_inc(interp) NOOP
+
+#define MP_INTERP_REFCNT_dec(interp) NOOP
+
+#define MP_HAS_INTERP(interp) (1)
+
+#define MP_aTHX 0
+
+#endif /* USE_ITHREADS */
+
+#endif /* MODPERL_INTERP_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_io.c b/2_0_13/src/modules/perl/modperl_io.c
new file mode 100644
index 0000000..7a0baf0
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_io.c
@@ -0,0 +1,183 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+#define TIEHANDLE(handle,r) \
+modperl_io_handle_tie(aTHX_ handle, "Apache2::RequestRec", (void *)r)
+
+#define TIED(handle) \
+modperl_io_handle_tied(aTHX_ handle, "Apache2::RequestRec")
+
+MP_INLINE void modperl_io_handle_tie(pTHX_ GV *handle,
+ char *classname, void *ptr)
+{
+ SV *obj = modperl_ptr2obj(aTHX_ classname, ptr);
+
+ modperl_io_handle_untie(aTHX_ handle);
+
+ sv_magic(TIEHANDLE_SV(handle), obj, PERL_MAGIC_tiedscalar, (char *)NULL, 0);
+
+ SvREFCNT_dec(obj); /* since sv_magic did SvREFCNT_inc */
+
+ MP_TRACE_r(MP_FUNC, "tie *%s(0x%lx) => %s, REFCNT=%d",
+ GvNAME(handle), (unsigned long)handle, classname,
+ SvREFCNT(TIEHANDLE_SV(handle)));
+}
+
+MP_INLINE GV *modperl_io_tie_stdin(pTHX_ request_rec *r)
+{
+#if defined(MP_IO_TIE_SFIO)
+ /* XXX */
+#else
+ dHANDLE("STDIN");
+
+ if (TIED(handle)) {
+ return handle;
+ }
+
+ TIEHANDLE(handle, r);
+
+ return handle;
+#endif
+}
+
+MP_INLINE GV *modperl_io_tie_stdout(pTHX_ request_rec *r)
+{
+#if defined(MP_IO_TIE_SFIO)
+ /* XXX */
+#else
+ dHANDLE("STDOUT");
+
+ if (TIED(handle)) {
+ return handle;
+ }
+
+ IoFLUSH_off(PL_defoutgv); /* $|=0 */
+
+ TIEHANDLE(handle, r);
+
+ return handle;
+#endif
+}
+
+MP_INLINE int modperl_io_handle_tied(pTHX_ GV *handle, char *classname)
+{
+ MAGIC *mg;
+ SV *sv = TIEHANDLE_SV(handle);
+
+ if (SvMAGICAL(sv) && (mg = mg_find(sv, PERL_MAGIC_tiedscalar))) {
+ char *package = HvNAME(SvSTASH((SV*)SvRV(mg->mg_obj)));
+
+ if (!strEQ(package, classname)) {
+ MP_TRACE_r(MP_FUNC, "%s tied to %s", GvNAME(handle), package);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+MP_INLINE void modperl_io_handle_untie(pTHX_ GV *handle)
+{
+#ifdef MP_TRACE
+ if (mg_find(TIEHANDLE_SV(handle), PERL_MAGIC_tiedscalar)) {
+ MP_TRACE_r(MP_FUNC, "untie *%s(0x%lx), REFCNT=%d",
+ GvNAME(handle), (unsigned long)handle,
+ SvREFCNT(TIEHANDLE_SV(handle)));
+ }
+#endif
+
+ sv_unmagic(TIEHANDLE_SV(handle), PERL_MAGIC_tiedscalar);
+}
+
+MP_INLINE static void
+modperl_io_perlio_override_stdhandle(pTHX_ request_rec *r, int mode)
+{
+ dHANDLE(mode == O_RDONLY ? "STDIN" : "STDOUT");
+ int status;
+ SV *sv = sv_newmortal();
+
+ MP_TRACE_o(MP_FUNC, "start STD%s", mode == O_RDONLY ? "IN" : "OUT");
+
+ save_gp(handle, 1);
+
+ sv_setref_pv(sv, "Apache2::RequestRec", (void*)r);
+ status = do_openn(handle, mode == O_RDONLY ? "<:Apache2" : ">:Apache2",
+ 9, FALSE, mode, 0, (PerlIO *)NULL, &sv, 1);
+ if (status == 0) {
+ Perl_croak(aTHX_ "Failed to open STD%s: %" SVf,
+ mode == O_RDONLY ? "IN" : "OUT", get_sv("!", TRUE));
+ }
+
+ MP_TRACE_o(MP_FUNC, "end STD%s", mode==O_RDONLY ? "IN" : "OUT");
+}
+
+MP_INLINE static void
+modperl_io_perlio_restore_stdhandle(pTHX_ int mode)
+{
+ GV *handle_orig = gv_fetchpv(mode == O_RDONLY ? "STDIN" : "STDOUT",
+ FALSE, SVt_PVIO);
+
+ MP_TRACE_o(MP_FUNC, "start STD%s", mode == O_RDONLY ? "IN" : "OUT");
+
+ /* since closing unflushed STDOUT may trigger a subrequest
+ * (e.g. via mod_include), resulting in potential another response
+ * handler call, which may try to close STDOUT too. We will
+ * segfault, if that subrequest doesn't return before the the top
+ * level STDOUT is attempted to be closed. To prevent this
+ * situation always explicitly flush STDOUT, before reopening it.
+ */
+ if (mode != O_RDONLY &&
+ GvIOn(handle_orig) && IoOFP(GvIOn(handle_orig)) &&
+ (PerlIO_flush(IoOFP(GvIOn(handle_orig))) == -1)) {
+ Perl_croak(aTHX_ "Failed to flush STDOUT: %" SVf, get_sv("!", TRUE));
+ }
+
+ /* close the overriding filehandle */
+ do_close(handle_orig, FALSE);
+
+ MP_TRACE_o(MP_FUNC, "end STD%s", mode == O_RDONLY ? "IN" : "OUT");
+}
+
+MP_INLINE GV *modperl_io_perlio_override_stdin(pTHX_ request_rec *r)
+{
+ modperl_io_perlio_override_stdhandle(aTHX_ r, O_RDONLY);
+ return NULL;
+}
+
+MP_INLINE GV *modperl_io_perlio_override_stdout(pTHX_ request_rec *r)
+{
+ modperl_io_perlio_override_stdhandle(aTHX_ r, O_WRONLY);
+ return NULL;
+}
+
+MP_INLINE void modperl_io_perlio_restore_stdin(pTHX_ GV *handle)
+{
+ modperl_io_perlio_restore_stdhandle(aTHX_ O_RDONLY);
+}
+
+MP_INLINE void modperl_io_perlio_restore_stdout(pTHX_ GV *handle)
+{
+ modperl_io_perlio_restore_stdhandle(aTHX_ O_WRONLY);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_io.h b/2_0_13/src/modules/perl/modperl_io.h
new file mode 100644
index 0000000..cfb9402
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_io.h
@@ -0,0 +1,84 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_IO_H
+#define MODPERL_IO_H
+
+#include "modperl_io_apache.h"
+
+/*
+ * bleedperl change #11639 switch tied handle magic
+ * from living in the gv to the GvIOp(gv), so we have to deal
+ * with both to support 5.6.x
+ */
+#if MP_PERL_VERSION_AT_LEAST(5, 7, 0)
+# define TIEHANDLE_SV(handle) (SV*)GvIOp((SV*)handle)
+#else
+# define TIEHANDLE_SV(handle) (SV*)handle
+#endif
+
+#define dHANDLE(name) GV *handle = gv_fetchpv(name, TRUE, SVt_PVIO)
+
+#define IoFLUSH_off(gv) \
+IoFLAGS(GvIOp((gv))) &= ~IOf_FLUSH
+
+#define IoFLUSH_on(gv) \
+IoFLAGS(GvIOp((gv))) |= IOf_FLUSH
+
+#define IoFLUSH(gv) \
+(IoFLAGS(GvIOp((gv))) & IOf_FLUSH)
+
+MP_INLINE void modperl_io_handle_tie(pTHX_ GV *handle,
+ char *classname, void *ptr);
+MP_INLINE GV *modperl_io_tie_stdout(pTHX_ request_rec *r);
+
+MP_INLINE GV *modperl_io_tie_stdin(pTHX_ request_rec *r);
+
+MP_INLINE int modperl_io_handle_tied(pTHX_ GV *handle, char *classname);
+
+MP_INLINE void modperl_io_handle_untie(pTHX_ GV *handle);
+
+MP_INLINE GV *modperl_io_perlio_override_stdin(pTHX_ request_rec *r);
+
+MP_INLINE GV *modperl_io_perlio_override_stdout(pTHX_ request_rec *r);
+
+MP_INLINE void modperl_io_perlio_restore_stdin(pTHX_ GV *handle);
+
+MP_INLINE void modperl_io_perlio_restore_stdout(pTHX_ GV *handle);
+
+#if defined(MP_IO_TIE_SFIO)
+ /* XXX */
+#elif defined(MP_IO_TIE_PERLIO)
+#define modperl_io_override_stdin modperl_io_perlio_override_stdin
+#define modperl_io_override_stdout modperl_io_perlio_override_stdout
+#define modperl_io_restore_stdin modperl_io_perlio_restore_stdin
+#define modperl_io_restore_stdout modperl_io_perlio_restore_stdout
+#else
+#define modperl_io_override_stdin modperl_io_tie_stdin
+#define modperl_io_override_stdout modperl_io_tie_stdout
+#define modperl_io_restore_stdin modperl_io_handle_untie
+#define modperl_io_restore_stdout modperl_io_handle_untie
+#endif
+
+
+#endif /* MODPERL_IO_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_io_apache.c b/2_0_13/src/modules/perl/modperl_io_apache.c
new file mode 100644
index 0000000..c10031c
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_io_apache.c
@@ -0,0 +1,343 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+#ifdef MP_IO_TIE_PERLIO
+
+/***************************
+ * The PerlIO Apache layer *
+ ***************************/
+
+/* PerlIO ":Apache2" layer is used to use the Apache callbacks to read
+ * from STDIN and write to STDOUT. The PerlIO API is documented in
+ * perliol.pod */
+
+typedef struct {
+ struct _PerlIO base;
+ request_rec *r;
+} PerlIOApache;
+
+/* _open just allocates the layer, _pushed does the real job of
+ * filling the data in */
+static PerlIO *
+PerlIOApache_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers, IV n,
+ const char *mode, int fd, int imode, int perm,
+ PerlIO *f, int narg, SV **args)
+{
+ if (!f) {
+ f = PerlIO_allocate(aTHX);
+ }
+ if ( (f = PerlIO_push(aTHX_ f, self, mode, args[0])) ) {
+ PerlIOBase(f)->flags |= PERLIO_F_OPEN;
+ }
+
+ MP_TRACE_o(MP_FUNC, "mode %s", mode);
+
+ return f;
+}
+
+/* this callback is used by pushed() and binmode() to add the layer */
+static IV
+PerlIOApache_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg,
+ PerlIO_funcs *tab)
+{
+ IV code;
+ PerlIOApache *st = PerlIOSelf(f, PerlIOApache);
+
+ if (arg) {
+ st->r = modperl_sv2request_rec(aTHX_ arg);
+ MP_TRACE_o(MP_FUNC, "stored request_rec obj: 0x%lx", st->r);
+ }
+ else {
+ Perl_croak(aTHX_"failed to insert the :Apache2 layer. "
+ "Apache2::RequestRec object argument is required");
+ /* XXX: try to get Apache2->request? */
+ }
+
+ /* this method also sets the right flags according to the
+ * 'mode' */
+ code = PerlIOBase_pushed(aTHX_ f, mode, (SV *)NULL, tab);
+
+ return code;
+}
+
+static SV *
+PerlIOApache_getarg(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
+{
+ PerlIOApache *st = PerlIOSelf(f, PerlIOApache);
+ SV *sv;
+
+ if (!st->r) {
+ Perl_croak(aTHX_ "an attempt to getarg from a stale io handle");
+ }
+
+ sv = newSV(0);
+ sv_setref_pv(sv, "Apache2::RequestRec", (void*)(st->r));
+
+ MP_TRACE_o(MP_FUNC, "retrieved request_rec obj: 0x%lx", st->r);
+
+ return sv;
+}
+
+static IV
+PerlIOApache_fileno(pTHX_ PerlIO *f)
+{
+ /* XXX: we could return STDIN => 0, STDOUT => 1, but that wouldn't
+ * be correct, as the IO goes through the socket, may be we should
+ * return the filedescriptor of the socket?
+ *
+ * -1 in this case indicates that the layer cannot provide fileno
+ */
+ MP_TRACE_o(MP_FUNC, "did nothing");
+ return -1;
+}
+
+static SSize_t
+PerlIOApache_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
+{
+ PerlIOApache *st = PerlIOSelf(f, PerlIOApache);
+ request_rec *r = st->r;
+
+ if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD) ||
+ PerlIOBase(f)->flags & (PERLIO_F_EOF|PERLIO_F_ERROR)) {
+ return 0;
+ }
+
+ return modperl_request_read(aTHX_ r, (char*)vbuf, count);
+}
+
+static SSize_t
+PerlIOApache_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
+{
+ PerlIOApache *st = PerlIOSelf(f, PerlIOApache);
+ modperl_config_req_t *rcfg = modperl_config_req_get(st->r);
+ apr_size_t bytes = 0;
+
+ if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE)) {
+ return 0;
+ }
+
+ MP_CHECK_WBUCKET_INIT("print");
+
+ MP_TRACE_o(MP_FUNC, "%4db [%s]", count,
+ MP_TRACE_STR_TRUNC(rcfg->wbucket->pool, vbuf, count));
+
+ MP_RUN_CROAK(modperl_wbucket_write(aTHX_ rcfg->wbucket, vbuf, &count),
+ ":Apache2 IO write");
+
+ bytes += count;
+
+ return (SSize_t) bytes;
+}
+
+static IV
+PerlIOApache_flush(pTHX_ PerlIO *f)
+{
+ PerlIOApache *st = PerlIOSelf(f, PerlIOApache);
+ modperl_config_req_t *rcfg;
+
+ if (!st->r) {
+ Perl_warn(aTHX_ "an attempt to flush a stale IO handle");
+ return -1;
+ }
+
+ /* no flush on readonly io handle */
+ if (! (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) ) {
+ return -1;
+ }
+
+ rcfg = modperl_config_req_get(st->r);
+
+ MP_CHECK_WBUCKET_INIT("flush");
+
+ MP_TRACE_o(MP_FUNC, "%4db [%s]", rcfg->wbucket->outcnt,
+ MP_TRACE_STR_TRUNC(rcfg->wbucket->pool,
+ rcfg->wbucket->outbuf,
+ rcfg->wbucket->outcnt));
+
+ MP_RUN_CROAK_RESET_OK(st->r->server,
+ modperl_wbucket_flush(rcfg->wbucket, FALSE),
+ ":Apache2 IO flush");
+
+ return 0;
+}
+
+/* 5.8.0 doesn't export PerlIOBase_noop_fail, so we duplicate it here */
+static IV PerlIOApache_noop_fail(pTHX_ PerlIO *f)
+{
+ return -1;
+}
+
+static IV
+PerlIOApache_close(pTHX_ PerlIO *f)
+{
+ IV code = PerlIOBase_close(aTHX_ f);
+ PerlIOApache *st = PerlIOSelf(f, PerlIOApache);
+
+ MP_TRACE_o(MP_FUNC, "done with request_rec obj: 0x%lx", st->r);
+ /* prevent possible bugs where a stale r will be attempted to be
+ * reused (e.g. dupped filehandle) */
+ st->r = NULL;
+
+ return code;
+}
+
+static IV
+PerlIOApache_popped(pTHX_ PerlIO *f)
+{
+ /* XXX: just temp for tracing */
+ MP_TRACE_o(MP_FUNC, "done");
+ return PerlIOBase_popped(aTHX_ f);
+}
+
+
+static PerlIO_funcs PerlIO_Apache = {
+ sizeof(PerlIO_funcs),
+ "Apache2",
+ sizeof(PerlIOApache),
+ PERLIO_K_MULTIARG | PERLIO_K_RAW,
+ PerlIOApache_pushed,
+ PerlIOApache_popped,
+ PerlIOApache_open,
+ PerlIOBase_binmode,
+ PerlIOApache_getarg,
+ PerlIOApache_fileno,
+ PerlIOBase_dup,
+ PerlIOApache_read,
+ PerlIOBase_unread,
+ PerlIOApache_write,
+ NULL, /* can't seek on STD{IN|OUT}, fail on call*/
+ NULL, /* can't tell on STD{IN|OUT}, fail on call*/
+ PerlIOApache_close,
+ PerlIOApache_flush,
+ PerlIOApache_noop_fail, /* fill */
+ PerlIOBase_eof,
+ PerlIOBase_error,
+ PerlIOBase_clearerr,
+ PerlIOBase_setlinebuf,
+ NULL, /* get_base */
+ NULL, /* get_bufsiz */
+ NULL, /* get_ptr */
+ NULL, /* get_cnt */
+ NULL, /* set_ptrcnt */
+};
+
+/* ***** End of PerlIOApache tab ***** */
+
+MP_INLINE void modperl_io_apache_init(pTHX)
+{
+ PerlIO_define_layer(aTHX_ &PerlIO_Apache);
+}
+
+#endif /* defined MP_IO_TIE_PERLIO */
+
+/****** Other request IO functions *******/
+
+
+MP_INLINE SSize_t modperl_request_read(pTHX_ request_rec *r,
+ char *buffer, Size_t len)
+{
+ SSize_t total = 0;
+ Size_t wanted = len;
+ int seen_eos = 0;
+ char *tmp = buffer;
+ apr_bucket_brigade *bb;
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ if (bb == NULL) {
+ r->connection->keepalive = AP_CONN_CLOSE;
+ Perl_croak(aTHX_ "failed to create bucket brigade");
+ }
+
+ do {
+ apr_size_t read;
+ apr_status_t rc;
+
+ rc = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+ APR_BLOCK_READ, len);
+ if (rc != APR_SUCCESS) {
+ /* if we fail here, we want to stop trying to read data
+ * from the client.
+ */
+ r->connection->keepalive = AP_CONN_CLOSE;
+ apr_brigade_destroy(bb);
+ modperl_croak(aTHX_ rc, "Apache2::RequestIO::read");
+ }
+
+ /* If this fails, it means that a filter is written
+ * incorrectly and that it needs to learn how to properly
+ * handle APR_BLOCK_READ requests by returning data when
+ * requested.
+ */
+ if (APR_BRIGADE_EMPTY(bb)) {
+ apr_brigade_destroy(bb);
+ /* we can't tell which filter is broken, since others may
+ * just pass data through */
+ Perl_croak(aTHX_ "Apache2::RequestIO::read: "
+ "Aborting read from client. "
+ "One of the input filters is broken. "
+ "It returned an empty bucket brigade for "
+ "the APR_BLOCK_READ mode request");
+ }
+
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
+ seen_eos = 1;
+ }
+
+ read = len;
+ rc = apr_brigade_flatten(bb, tmp, &read);
+ if (rc != APR_SUCCESS) {
+ apr_brigade_destroy(bb);
+ modperl_croak(aTHX_ rc, "Apache2::RequestIO::read");
+ }
+
+ total += read;
+ tmp += read;
+ len -= read;
+
+ /* XXX: what happens if the downstream filter returns more
+ * data than the caller has asked for? We can't return more
+ * data than requested, so it needs to be stored somewhere and
+ * dealt with on the subsequent calls to this function. or may
+ * be we should just assert, blaming a bad filter. at the
+ * moment I couldn't find a spec telling whether it's wrong
+ * for the filter to return more data than it was asked for in
+ * the AP_MODE_READBYTES mode.
+ */
+
+ apr_brigade_cleanup(bb);
+
+ } while (len > 0 && !seen_eos);
+
+ apr_brigade_destroy(bb);
+
+ MP_TRACE_o(MP_FUNC, "wanted %db, read %db [%s]", wanted, total,
+ MP_TRACE_STR_TRUNC(r->pool, buffer, total));
+
+ return total;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_io_apache.h b/2_0_13/src/modules/perl/modperl_io_apache.h
new file mode 100644
index 0000000..a372222
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_io_apache.h
@@ -0,0 +1,67 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_IO_APACHE_H
+#define MODPERL_IO_APACHE_H
+
+#ifdef PERLIO_LAYERS
+
+#include "perliol.h"
+/* XXX: should this be a Makefile.PL config option? */
+#define MP_IO_TIE_PERLIO
+
+#include "apr_portable.h"
+#include "apr_file_io.h"
+#include "apr_errno.h"
+
+typedef enum {
+ MODPERL_IO_APACHE_HOOK_READ,
+ MODPERL_IO_APACHE_HOOK_WRITE
+} modperl_io_apache_hook_e;
+
+#define PERLIO_Apache_DEBUG
+
+MP_INLINE void modperl_io_apache_init(pTHX);
+
+#else /* #ifdef PERLIO_LAYERS */
+
+#define modperl_io_apache_init(pTHX)
+
+#endif /* #ifdef PERLIO_LAYERS */
+
+/**
+ * read 'len' bytes from the request record 'r' into 'buffer'
+ *
+ * this call will block until all 'len' bytes are read, eof is reached
+ * or will return an error otherwise
+ *
+ * @param r request record
+ * @param buffer preallocated buffer of size 'len' to store the data in
+ * @param len how many bytes to read
+ * @return how many bytes were read,
+ * -1 on error (in which case ERRSV ($!) is set)
+ */
+MP_INLINE SSize_t modperl_request_read(pTHX_ request_rec *r,
+ char *buffer, Size_t len);
+
+#endif /* MODPERL_IO_APACHE_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_log.c b/2_0_13/src/modules/perl/modperl_log.c
new file mode 100644
index 0000000..a806e00
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_log.c
@@ -0,0 +1,24 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_log.h"
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_log.h b/2_0_13/src/modules/perl/modperl_log.h
new file mode 100644
index 0000000..7e5f303
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_log.h
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_LOG_H
+#define MODPERL_LOG_H
+
+#include "modperl_common_log.h"
+#include "modperl_apache_includes.h"
+
+#define modperl_trace_level_set_apache(s, level) \
+ modperl_trace_level_set(s->error_log, level);
+
+#define modperl_log_warn(s, msg) \
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "%s", msg)
+
+#define modperl_log_error(s, msg) \
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "%s", msg)
+
+#define modperl_log_notice(s, msg) \
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "%s", msg)
+
+#define modperl_log_debug(s, msg) \
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", msg)
+
+#define modperl_log_reason(r, msg, file) \
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, \
+ "access to %s failed for %s, reason: %s", \
+ file, \
+ ap_get_remote_host(r->connection, \
+ r->per_dir_config, REMOTE_NAME, \
+ NULL), \
+ msg)
+
+#endif /* MODPERL_LOG_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_mgv.c b/2_0_13/src/modules/perl/modperl_mgv.c
new file mode 100644
index 0000000..c6286f0
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_mgv.c
@@ -0,0 +1,541 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/*
+ * mgv = ModPerl Glob Value || Mostly Glob Value
+ * as close to GV as we can get without actually using a GV
+ * need config structures to be free of Perl structures
+ */
+
+#define modperl_mgv_new_w_name(mgv, p, n, copy) \
+ mgv = modperl_mgv_new(p); \
+ mgv->len = strlen(n); \
+ mgv->name = (copy ? apr_pstrndup(p, n, mgv->len) : n)
+
+#define modperl_mgv_new_name(mgv, p, n) \
+ modperl_mgv_new_w_name(mgv, p, n, 1)
+
+#define modperl_mgv_new_namen(mgv, p, n) \
+ modperl_mgv_new_w_name(mgv, p, n, 0)
+
+int modperl_mgv_equal(modperl_mgv_t *mgv1,
+ modperl_mgv_t *mgv2)
+{
+ for (; mgv1 && mgv2; mgv1=mgv1->next, mgv2=mgv2->next) {
+ if (mgv1->hash != mgv2->hash) {
+ return FALSE;
+ }
+ if (mgv1->len != mgv2->len) {
+ return FALSE;
+ }
+ if (memNE(mgv1->name, mgv2->name, mgv1->len)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+modperl_mgv_t *modperl_mgv_new(apr_pool_t *p)
+{
+ return (modperl_mgv_t *)apr_pcalloc(p, sizeof(modperl_mgv_t));
+}
+
+#define modperl_mgv_get_next(mgv) \
+ if (mgv->name) { \
+ mgv->next = modperl_mgv_new(p); \
+ mgv = mgv->next; \
+ }
+
+#define modperl_mgv_hash(mgv) \
+ PERL_HASH(mgv->hash, mgv->name, mgv->len)
+ /* MP_TRACE_h(MP_FUNC, "%s...hash=%ld", mgv->name, mgv->hash) */
+
+modperl_mgv_t *modperl_mgv_compile(pTHX_ apr_pool_t *p,
+ register const char *name)
+{
+ register const char *namend;
+ I32 len;
+ modperl_mgv_t *symbol = modperl_mgv_new(p);
+ modperl_mgv_t *mgv = symbol;
+
+ /* @mgv = split '::', $name */
+ for (namend = name; *namend; namend++) {
+ if (*namend == ':' && namend[1] == ':') {
+ if ((len = (namend - name)) > 0) {
+ modperl_mgv_get_next(mgv);
+ mgv->name = apr_palloc(p, len+3);
+ Copy(name, mgv->name, len, char);
+ mgv->name[len++] = ':';
+ mgv->name[len++] = ':';
+ mgv->name[len] = '\0';
+ mgv->len = len;
+ modperl_mgv_hash(mgv);
+ }
+ name = namend + 2;
+ }
+ }
+
+ modperl_mgv_get_next(mgv);
+
+ mgv->len = namend - name;
+ mgv->name = apr_pstrndup(p, name, mgv->len);
+ modperl_mgv_hash(mgv);
+
+ return symbol;
+}
+
+void modperl_mgv_append(pTHX_ apr_pool_t *p, modperl_mgv_t *symbol,
+ const char *name)
+{
+ modperl_mgv_t *mgv = symbol;
+
+ while (mgv->next) {
+ mgv = mgv->next;
+ }
+
+ mgv->name = apr_pstrcat(p, mgv->name, "::", NULL);
+ mgv->len += 2;
+ modperl_mgv_hash(mgv);
+
+ mgv->next = modperl_mgv_compile(aTHX_ p, name);
+}
+
+/* faster replacement for gv_fetchpv() */
+GV *modperl_mgv_lookup(pTHX_ modperl_mgv_t *symbol)
+{
+ HV *stash = PL_defstash;
+ modperl_mgv_t *mgv;
+
+ if (!symbol->hash) {
+ /* special case for MyClass->handler */
+ return (GV*)sv_2mortal(newSVpvn(symbol->name, symbol->len));
+ }
+
+ for (mgv = symbol; mgv; mgv = mgv->next) {
+ HE *he = hv_fetch_he(stash, mgv->name, mgv->len, mgv->hash);
+ if (he) {
+ if (mgv->next) {
+ stash = GvHV((GV *)HeVAL(he));
+ }
+ else {
+ return (GV *)HeVAL(he);
+ }
+ }
+ else {
+ return (GV *)NULL;
+ }
+ }
+
+ return (GV *)NULL;
+}
+
+#ifdef USE_ITHREADS
+MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p)
+{
+ MP_dSCFG(s);
+ GV *gv = modperl_mgv_lookup(aTHX_ symbol);
+
+ if (gv || !MpSrvPARENT(scfg)) {
+ return gv;
+ }
+
+ /*
+ * this VirtualHost has its own parent interpreter
+ * must require the module again with this server's THX
+ */
+ modperl_mgv_require_module(aTHX_ symbol, s, p);
+
+ return modperl_mgv_lookup(aTHX_ symbol);
+}
+#else
+MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p)
+{
+ return modperl_mgv_lookup(aTHX_ symbol);
+}
+#endif
+
+/* currently used for complex filters attributes parsing */
+/* XXX: may want to generalize it for any handlers */
+#define MODPERL_MGV_DEEP_RESOLVE(handler, p) \
+ if (handler->attrs & MP_FILTER_HAS_INIT_HANDLER) { \
+ modperl_filter_resolve_init_handler(aTHX_ handler, p); \
+ }
+
+int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler,
+ apr_pool_t *p, const char *name, int logfailure)
+{
+ CV *cv;
+ GV *gv;
+ HV *stash = (HV *)NULL;
+ char *handler_name = "handler";
+ char *tmp;
+
+ if (MpHandlerANON(handler)) {
+ /* already resolved anonymous handler */
+ return 1;
+ }
+
+ if (strnEQ(name, "sub ", 4)) {
+ SV *sv;
+ CV *cv;
+ MpHandlerPARSED_On(handler);
+ MpHandlerANON_On(handler);
+
+ ENTER;SAVETMPS;
+ sv = eval_pv(name, TRUE);
+ if (!(SvROK(sv) && (cv = (CV*)SvRV(sv)) && (CvFLAGS(cv) & CVf_ANON))) {
+
+ Perl_croak(aTHX_ "expected anonymous sub, got '%s'\n", name);
+ }
+
+#ifdef USE_ITHREADS
+ handler->cv = NULL;
+ handler->name = NULL;
+ handler->mgv_obj = modperl_handler_anon_next(aTHX_ p);
+ modperl_handler_anon_add(aTHX_ handler->mgv_obj, cv);
+ MP_TRACE_h(MP_FUNC, "new anon handler");
+#else
+ SvREFCNT_inc(cv);
+ handler->cv = cv;
+ handler->name = NULL;
+ MP_TRACE_h(MP_FUNC, "new cached-cv anon handler");
+#endif
+
+ FREETMPS;LEAVE;
+
+ return 1;
+ }
+
+ if ((tmp = strstr((char *)name, "->"))) {
+ int package_len = strlen(name) - strlen(tmp);
+ char *package = apr_pstrndup(p, name, package_len);
+
+ name = package;
+ handler_name = &tmp[2];
+
+ MpHandlerMETHOD_On(handler);
+
+ if (*package == '$') {
+ GV *gv;
+ SV *obj;
+
+ handler->mgv_obj = modperl_mgv_compile(aTHX_ p, package + 1);
+ gv = modperl_mgv_lookup(aTHX_ handler->mgv_obj);
+ obj = gv ? GvSV(gv) : (SV *)NULL;
+
+ if (SvTRUE(obj)) {
+ if (SvROK(obj) && sv_isobject(obj)) {
+ stash = SvSTASH(SvRV(obj));
+ MpHandlerOBJECT_On(handler);
+ MP_TRACE_h(MP_FUNC, "handler object %s isa %s",
+ package, HvNAME(stash));
+ }
+ else {
+ MP_TRACE_h(MP_FUNC, "%s is not an object, pv=%s",
+ package, SvPV_nolen(obj));
+ return 0;
+ }
+ }
+ else {
+ MP_TRACE_h(MP_FUNC, "failed to thaw %s", package);
+ return 0;
+ }
+ }
+
+ if (!stash) {
+ if ((stash = gv_stashpvn(package, package_len, FALSE))) {
+ MP_TRACE_h(MP_FUNC, "handler method %s isa %s",
+ name, HvNAME(stash));
+ }
+ }
+ }
+ else {
+ if ((cv = get_cv(name, FALSE))) {
+ handler->attrs = *modperl_code_attrs(aTHX_ cv);
+ handler->mgv_cv =
+ modperl_mgv_compile(aTHX_ p, HvNAME(GvSTASH(CvGV(cv))));
+ modperl_mgv_append(aTHX_ p, handler->mgv_cv, GvNAME(CvGV(cv)));
+ MpHandlerPARSED_On(handler);
+ MODPERL_MGV_DEEP_RESOLVE(handler, p);
+ return 1;
+ }
+ }
+
+ if (!stash && MpHandlerAUTOLOAD(handler)) {
+ if (!modperl_perl_module_loaded(aTHX_ name)) { /* not in %INC */
+ MP_TRACE_h(MP_FUNC,
+ "package %s not in %INC, attempting to load it",
+ name);
+
+ if (modperl_require_module(aTHX_ name, logfailure)) {
+ MP_TRACE_h(MP_FUNC, "loaded %s package", name);
+ }
+ else {
+ if (logfailure) {
+ /* the caller doesn't handle the error checking */
+ Perl_croak(aTHX_ "failed to load %s package\n", name);
+ }
+ else {
+ /* the caller handles the error checking */
+ MP_TRACE_h(MP_FUNC, "failed to load %s package", name);
+ return 0;
+ }
+ }
+ }
+ else {
+ MP_TRACE_h(MP_FUNC, "package %s seems to be loaded", name);
+ }
+ }
+
+ /* try to lookup the stash only after loading the module, to avoid
+ * the case where a stash is autovivified by a user before the
+ * module was loaded, preventing from loading the module
+ */
+ if (!(stash || (stash = gv_stashpv(name, FALSE)))) {
+ MP_TRACE_h(MP_FUNC, "%s's stash is not found", name);
+ return 0;
+ }
+
+ if ((gv = gv_fetchmethod(stash, handler_name)) && (cv = GvCV(gv))) {
+ if (CvFLAGS(cv) & CVf_METHOD) { /* sub foo : method {}; */
+ MpHandlerMETHOD_On(handler);
+ }
+
+ if (!stash) {
+ return 0;
+ }
+
+
+ if (MpHandlerMETHOD(handler) && !handler->mgv_obj) {
+ char *name = HvNAME(stash);
+ if (!name) {
+ name = "";
+ }
+ modperl_mgv_new_name(handler->mgv_obj, p, name);
+ }
+
+ handler->attrs = *modperl_code_attrs(aTHX_ cv);
+ /* note: this is the real function after @ISA lookup */
+ handler->mgv_cv = modperl_mgv_compile(aTHX_ p, HvNAME(GvSTASH(gv)));
+ modperl_mgv_append(aTHX_ p, handler->mgv_cv, handler_name);
+
+ MpHandlerPARSED_On(handler);
+ MP_TRACE_h(MP_FUNC, "found `%s' in class `%s' as a %s",
+ handler_name, HvNAME(stash),
+ MpHandlerMETHOD(handler) ? "method" : "function");
+ MODPERL_MGV_DEEP_RESOLVE(handler, p);
+ return 1;
+ }
+
+ /* at least modperl_hash_handlers needs to verify that an
+ * autoloaded-marked handler needs to be loaded, since it doesn't
+ * check success failure, and handlers marked to be autoloaded are
+ * the same as PerlModule and the failure should be fatal */
+ if (MpHandlerAUTOLOAD(handler)) {
+ Perl_croak(aTHX_ "failed to resolve handler %s\n", name);
+ }
+
+#ifdef MP_TRACE
+ /* complain only if the class was actually loaded/created */
+ if (stash) {
+ MP_TRACE_h(MP_FUNC, "`%s' not found in class `%s'",
+ handler_name, name);
+ }
+#endif
+
+ return 0;
+}
+
+modperl_mgv_t *modperl_mgv_last(modperl_mgv_t *symbol)
+{
+ while (symbol->next) {
+ symbol = symbol->next;
+ }
+
+ return symbol;
+}
+
+char *modperl_mgv_last_name(modperl_mgv_t *symbol)
+{
+ symbol = modperl_mgv_last(symbol);
+ return symbol->name;
+}
+
+char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol,
+ apr_pool_t *p, int package)
+{
+ char *string, *ptr;
+ modperl_mgv_t *mgv;
+ int len = 0;
+
+ for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) {
+ len += mgv->len;
+ }
+
+ ptr = string = apr_palloc(p, len+1);
+
+ for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) {
+ Copy(mgv->name, ptr, mgv->len, char);
+ ptr += mgv->len;
+ }
+
+ if (package) {
+ *(ptr-2) = '\0'; /* trim trailing :: */
+ }
+ else {
+ *ptr = '\0';
+ }
+
+ return string;
+}
+
+#ifdef USE_ITHREADS
+int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p)
+{
+ char *package =
+ modperl_mgv_as_string(aTHX_ symbol, p, 1);
+
+ if (modperl_require_module(aTHX_ package, TRUE)) {
+ MP_TRACE_h(MP_FUNC, "reloaded %s for server %s",
+ package, modperl_server_desc(s, p));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif
+
+/* precompute the hash(es) for handler names, preload handlers
+ * configured to be autoloaded */
+static void modperl_hash_handlers(pTHX_ apr_pool_t *p, server_rec *s,
+ MpAV *entry, void *data)
+{
+ MP_dSCFG(s);
+ int i;
+ modperl_handler_t **handlers;
+
+ if (!entry) {
+ return;
+ }
+
+ handlers = (modperl_handler_t **)entry->elts;
+
+ for (i=0; i < entry->nelts; i++) {
+ modperl_handler_t *handler = handlers[i];
+
+ if (MpHandlerFAKE(handler)) {
+ /* do nothing with fake handlers */
+ }
+ else if (MpHandlerPARSED(handler)) {
+#ifdef USE_ITHREADS
+ if ((MpSrvPARENT(scfg) && MpSrvAUTOLOAD(scfg))
+ && !modperl_mgv_lookup(aTHX_ handler->mgv_cv)) {
+ /*
+ * this VirtualHost has its own parent interpreter
+ * must require the module again with this server's THX
+ */
+ modperl_mgv_require_module(aTHX_ handler->mgv_cv,
+ s, p);
+ }
+#endif
+ MP_TRACE_h(MP_FUNC, "%s already resolved in server %s",
+ modperl_handler_name(handler),
+ modperl_server_desc(s, p));
+ }
+ else {
+ if (MpSrvAUTOLOAD(scfg)) {
+ MpHandlerAUTOLOAD_On(handler);
+ }
+
+ modperl_mgv_resolve(aTHX_ handler, p, handler->name, TRUE);
+ }
+ }
+}
+
+static int modperl_hash_handlers_dir(apr_pool_t *p, server_rec *s,
+ void *cfg, char *d, void *data)
+{
+ int i;
+ modperl_config_dir_t *dir_cfg = (modperl_config_dir_t *)cfg;
+ dTHXa(data);
+
+ if (!dir_cfg) {
+ return 1;
+ }
+
+ for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
+ modperl_hash_handlers(aTHX_ p, s, dir_cfg->handlers_per_dir[i], data);
+ }
+
+ return 1;
+}
+
+static int modperl_hash_handlers_srv(apr_pool_t *p, server_rec *s,
+ void *cfg, void *data)
+{
+ int i;
+ modperl_config_srv_t *scfg = (modperl_config_srv_t *)cfg;
+ dTHXa(data);
+
+ for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) {
+ modperl_hash_handlers(aTHX_ p, s,
+ scfg->handlers_per_srv[i], data);
+ }
+
+ for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) {
+ modperl_hash_handlers(aTHX_ p, s,
+ scfg->handlers_process[i], data);
+ }
+
+ for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) {
+ modperl_hash_handlers(aTHX_ p, s,
+ scfg->handlers_connection[i], data);
+ }
+
+ for (i=0; i < MP_HANDLER_NUM_FILES; i++) {
+ modperl_hash_handlers(aTHX_ p, s,
+ scfg->handlers_files[i], data);
+ }
+
+ return 1;
+}
+
+void modperl_mgv_hash_handlers(apr_pool_t *p, server_rec *s)
+{
+ MP_dINTERPa(NULL, NULL, s);
+ ap_pcw_walk_config(p, s, &perl_module,
+#ifdef USE_ITHREADS
+ aTHX,
+#else
+ NULL,
+#endif
+ modperl_hash_handlers_dir,
+ modperl_hash_handlers_srv);
+ MP_INTERP_PUTBACK(interp, aTHX);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_mgv.h b/2_0_13/src/modules/perl/modperl_mgv.h
new file mode 100644
index 0000000..50ce5b8
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_mgv.h
@@ -0,0 +1,65 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_MGV_H
+#define MODPERL_MGV_H
+
+modperl_mgv_t *modperl_mgv_new(apr_pool_t *p);
+
+int modperl_mgv_equal(modperl_mgv_t *mgv1,
+ modperl_mgv_t *mgv2);
+
+modperl_mgv_t *modperl_mgv_compile(pTHX_ apr_pool_t *p, const char *name);
+
+GV *modperl_mgv_lookup(pTHX_ modperl_mgv_t *symbol);
+
+GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p);
+
+int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler,
+ apr_pool_t *p, const char *name, int logfailure);
+
+void modperl_mgv_append(pTHX_ apr_pool_t *p, modperl_mgv_t *symbol,
+ const char *name);
+
+modperl_mgv_t *modperl_mgv_last(modperl_mgv_t *symbol);
+
+char *modperl_mgv_last_name(modperl_mgv_t *symbol);
+
+char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol,
+ apr_pool_t *p, int package);
+
+#ifdef USE_ITHREADS
+int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p);
+#endif
+
+void modperl_mgv_hash_handlers(apr_pool_t *p, server_rec *s);
+
+#define modperl_mgv_sv(sv) \
+(isGV(sv) ? GvSV(sv) : (SV*)sv)
+
+#define modperl_mgv_cv(sv) \
+GvCV(sv)
+
+#endif /* MODPERL_MGV_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_module.c b/2_0_13/src/modules/perl/modperl_module.c
new file mode 100644
index 0000000..e804bad
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_module.c
@@ -0,0 +1,911 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+typedef struct {
+ modperl_mgv_t *dir_create;
+ modperl_mgv_t *dir_merge;
+ modperl_mgv_t *srv_create;
+ modperl_mgv_t *srv_merge;
+ int namelen;
+} modperl_module_info_t;
+
+typedef struct {
+ server_rec *server;
+ modperl_module_info_t *minfo;
+} modperl_module_cfg_t;
+
+#define MP_MODULE_INFO(modp) \
+ (modperl_module_info_t *)modp->dynamic_load_handle
+
+#define MP_MODULE_CFG_MINFO(ptr) \
+ ((modperl_module_cfg_t *)ptr)->minfo
+
+static modperl_module_cfg_t *modperl_module_cfg_new(apr_pool_t *p)
+{
+ modperl_module_cfg_t *cfg =
+ (modperl_module_cfg_t *)apr_pcalloc(p, sizeof(*cfg));
+
+ return cfg;
+}
+
+static modperl_module_cmd_data_t *modperl_module_cmd_data_new(apr_pool_t *p)
+{
+ modperl_module_cmd_data_t *cmd_data =
+ (modperl_module_cmd_data_t *)apr_pcalloc(p, sizeof(*cmd_data));
+
+ return cmd_data;
+}
+
+static void *modperl_module_config_dir_create(apr_pool_t *p, char *dir)
+{
+ return modperl_module_cfg_new(p);
+}
+
+static void *modperl_module_config_srv_create(apr_pool_t *p, server_rec *s)
+{
+ return modperl_module_cfg_new(p);
+}
+
+static SV **modperl_module_config_hash_get(pTHX_ int create)
+{
+ SV **svp;
+
+ /* XXX: could make this lookup faster */
+ svp = hv_fetch(PL_modglobal,
+ "ModPerl::Module::ConfigTable",
+ MP_SSTRLEN("ModPerl::Module::ConfigTable"),
+ create);
+
+ return svp;
+}
+
+void modperl_module_config_table_set(pTHX_ PTR_TBL_t *table)
+{
+ SV **svp = modperl_module_config_hash_get(aTHX_ TRUE);
+ sv_setiv(*svp, PTR2IV(table));
+}
+
+PTR_TBL_t *modperl_module_config_table_get(pTHX_ int create)
+{
+ PTR_TBL_t *table = NULL;
+
+ SV *sv, **svp = modperl_module_config_hash_get(aTHX_ create);
+
+ if (!svp) {
+ return NULL;
+ }
+
+ sv = *svp;
+ if (!SvIOK(sv) && create) {
+ table = modperl_svptr_table_new(aTHX);
+ sv_setiv(sv, PTR2IV(table));
+ }
+ else {
+ table = INT2PTR(PTR_TBL_t *, SvIV(sv));
+ }
+
+ return table;
+}
+
+typedef struct {
+#ifdef USE_ITHREADS
+ modperl_interp_t *interp;
+#endif
+ PTR_TBL_t *table;
+ void *ptr;
+} config_obj_cleanup_t;
+
+/*
+ * any per-dir CREATE or MERGE that happens at request time
+ * needs to be removed from the pointer table.
+ */
+static apr_status_t modperl_module_config_obj_cleanup(void *data)
+{
+ config_obj_cleanup_t *cleanup =
+ (config_obj_cleanup_t *)data;
+#ifdef USE_ITHREADS
+ dTHXa(cleanup->interp->perl);
+ MP_ASSERT_CONTEXT(aTHX);
+#endif
+
+ modperl_svptr_table_delete(aTHX_ cleanup->table, cleanup->ptr);
+
+ MP_TRACE_c(MP_FUNC, "deleting ptr %pp from table %pp",
+ cleanup->ptr, cleanup->table);
+
+ MP_INTERP_PUTBACK(cleanup->interp, aTHX);
+
+ return APR_SUCCESS;
+}
+
+static void modperl_module_config_obj_cleanup_register(pTHX_
+ apr_pool_t *p,
+ PTR_TBL_t *table,
+ void *ptr)
+{
+ config_obj_cleanup_t *cleanup =
+ (config_obj_cleanup_t *)apr_palloc(p, sizeof(*cleanup));
+
+ cleanup->table = table;
+ cleanup->ptr = ptr;
+#ifdef USE_ITHREADS
+ cleanup->interp = modperl_thx_interp_get(aTHX);
+ MP_INTERP_REFCNT_inc(cleanup->interp);
+#endif
+
+ apr_pool_cleanup_register(p, cleanup,
+ modperl_module_config_obj_cleanup,
+ apr_pool_cleanup_null);
+}
+
+#define MP_CFG_MERGE_DIR 1
+#define MP_CFG_MERGE_SRV 2
+
+/*
+ * XXX: vhosts may have different parent interpreters.
+ */
+static void *modperl_module_config_merge(apr_pool_t *p,
+ void *basev, void *addv,
+ int type)
+{
+ GV *gv;
+ modperl_mgv_t *method;
+ modperl_module_cfg_t *mrg = NULL,
+ *tmp,
+ *base = (modperl_module_cfg_t *)basev,
+ *add = (modperl_module_cfg_t *)addv;
+ server_rec *s;
+ int is_startup;
+ PTR_TBL_t *table;
+ SV *mrg_obj = (SV *)NULL, *base_obj, *add_obj;
+ MP_dINTERP;
+
+ /* if the module is loaded in vhost, base==NULL */
+ tmp = (base && base->server) ? base : add;
+
+ if (tmp && !tmp->server) {
+ /* no directives for this module were encountered so far */
+ return basev;
+ }
+
+ s = tmp->server;
+ is_startup = (p == s->process->pconf);
+
+ MP_INTERP_POOLa(p, s);
+
+ table = modperl_module_config_table_get(aTHX_ TRUE);
+ base_obj = modperl_svptr_table_fetch(aTHX_ table, base);
+ add_obj = modperl_svptr_table_fetch(aTHX_ table, add);
+
+ if (!base_obj || (base_obj == add_obj)) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return addv;
+ }
+
+ mrg = modperl_module_cfg_new(p);
+ memcpy(mrg, tmp, sizeof(*mrg));
+
+ method = (type == MP_CFG_MERGE_DIR) ?
+ mrg->minfo->dir_merge :
+ mrg->minfo->srv_merge;
+
+ if (method && (gv = modperl_mgv_lookup(aTHX_ method))) {
+ int count;
+ dSP;
+
+ MP_TRACE_c(MP_FUNC, "calling %s->%s",
+ SvCLASS(base_obj), modperl_mgv_last_name(method));
+
+ ENTER;SAVETMPS;
+ PUSHMARK(sp);
+ XPUSHs(base_obj);XPUSHs(add_obj);
+
+ PUTBACK;
+ count = call_sv((SV*)GvCV(gv), G_EVAL|G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ mrg_obj = SvREFCNT_inc(POPs);
+ }
+
+ PUTBACK;
+ FREETMPS;LEAVE;
+
+ if (SvTRUE(ERRSV)) {
+ /* XXX: should die here. */
+ (void)modperl_errsv(aTHX_ HTTP_INTERNAL_SERVER_ERROR,
+ NULL, NULL);
+ }
+ }
+ else {
+ mrg_obj = SvREFCNT_inc(add_obj);
+ }
+
+ modperl_svptr_table_store(aTHX_ table, mrg, mrg_obj);
+
+ if (!is_startup) {
+ modperl_module_config_obj_cleanup_register(aTHX_ p, table, mrg);
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ return (void *)mrg;
+}
+
+static void *modperl_module_config_dir_merge(apr_pool_t *p,
+ void *basev, void *addv)
+{
+ return modperl_module_config_merge(p, basev, addv,
+ MP_CFG_MERGE_DIR);
+}
+
+static void *modperl_module_config_srv_merge(apr_pool_t *p,
+ void *basev, void *addv)
+{
+ return modperl_module_config_merge(p, basev, addv,
+ MP_CFG_MERGE_SRV);
+}
+
+#define modperl_bless_cmd_parms(parms) \
+ sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::CmdParms", (void *)parms))
+
+static const char *
+modperl_module_config_create_obj(pTHX_
+ apr_pool_t *p,
+ PTR_TBL_t *table,
+ modperl_module_cfg_t *cfg,
+ modperl_module_cmd_data_t *info,
+ modperl_mgv_t *method,
+ cmd_parms *parms,
+ SV **obj)
+{
+ const char *mname = info->modp->name;
+ modperl_module_info_t *minfo = MP_MODULE_INFO(info->modp);
+ GV *gv;
+ int is_startup = (p == parms->server->process->pconf);
+
+ /*
+ * XXX: if MPM is not threaded, we could modify the
+ * modperl_module_cfg_t * directly and avoid the ptr_table
+ * altogether.
+ */
+ if ((*obj = (SV*)modperl_svptr_table_fetch(aTHX_ table, cfg))) {
+ /* object already exists */
+ return NULL;
+ }
+
+ MP_TRACE_c(MP_FUNC, "%s cfg=0x%lx for %s.%s",
+ method ? modperl_mgv_last_name(method) : "NULL",
+ (unsigned long)cfg, mname, parms->cmd->name);
+
+ /* used by merge functions to get a Perl interp */
+ cfg->server = parms->server;
+ cfg->minfo = minfo;
+
+ if (method && (gv = modperl_mgv_lookup(aTHX_ method))) {
+ int count;
+ dSP;
+
+ ENTER;SAVETMPS;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSVpv(mname, minfo->namelen)));
+ XPUSHs(modperl_bless_cmd_parms(parms));
+
+ PUTBACK;
+ count = call_sv((SV*)GvCV(gv), G_EVAL|G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ *obj = SvREFCNT_inc(POPs);
+ }
+
+ PUTBACK;
+ FREETMPS;LEAVE;
+
+ if (SvTRUE(ERRSV)) {
+ return SvPVX(ERRSV);
+ }
+ }
+ else {
+ HV *stash = gv_stashpvn(mname, minfo->namelen, FALSE);
+ /* return bless {}, $class */
+ *obj = newRV_noinc((SV*)newHV());
+ *obj = sv_bless(*obj, stash);
+ }
+
+ if (!is_startup) {
+ modperl_module_config_obj_cleanup_register(aTHX_ p, table, cfg);
+ }
+
+ modperl_svptr_table_store(aTHX_ table, cfg, *obj);
+
+ return NULL;
+}
+
+#define PUSH_STR_ARG(arg) \
+ if (arg) XPUSHs(sv_2mortal(newSVpv(arg,0)))
+
+static const char *modperl_module_cmd_take123(cmd_parms *parms,
+ void *mconfig,
+ const char *one,
+ const char *two,
+ const char *three)
+{
+ modperl_module_cfg_t *cfg = (modperl_module_cfg_t *)mconfig;
+ const char *retval = NULL, *errmsg;
+ const command_rec *cmd = parms->cmd;
+ server_rec *s = parms->server;
+ apr_pool_t *p = parms->pool;
+ modperl_module_cmd_data_t *info =
+ (modperl_module_cmd_data_t *)cmd->cmd_data;
+ modperl_module_info_t *minfo = MP_MODULE_INFO(info->modp);
+ modperl_module_cfg_t *srv_cfg;
+ int modules_alias = 0;
+ int count;
+ PTR_TBL_t *table;
+ SV *obj = (SV *)NULL;
+ MP_dINTERP_POOLa(p, s);
+
+ table = modperl_module_config_table_get(aTHX_ TRUE);
+
+ if (s->is_virtual) {
+ MP_dSCFG(s);
+
+ /* if the Perl module is loaded in the base server and a vhost
+ * has configuration directives from that module, but no
+ * mod_perl.c directives, scfg == NULL when
+ * modperl_module_cmd_take123 is run. If the directive
+ * callback wants to do something with the mod_perl config
+ * object, it'll segfault, since it doesn't exist yet, because
+ * this happens before server configs are merged. So we create
+ * a temp struct and fill it in with things that might be
+ * needed by the Perl callback.
+ */
+ if (!scfg) {
+ scfg = modperl_config_srv_new(p, s);
+ modperl_set_module_config(s->module_config, scfg);
+ scfg->server = s;
+ }
+
+ /* if PerlLoadModule Foo is called from the base server, but
+ * Foo's directives are used inside a vhost, we need to
+ * temporary link to the base server config's 'modules'
+ * member. e.g. so Apache2::Module->get_config() can be called
+ * from a custom directive's callback, before the server/vhost
+ * config merge is performed
+ */
+ if (!scfg->modules) {
+ modperl_config_srv_t *base_scfg =
+ modperl_config_srv_get(modperl_global_get_server_rec());
+ if (base_scfg->modules) {
+ scfg->modules = base_scfg->modules;
+ modules_alias = 1;
+ }
+ }
+
+ }
+
+ errmsg = modperl_module_config_create_obj(aTHX_ p, table, cfg, info,
+ minfo->dir_create,
+ parms, &obj);
+
+ if (errmsg) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return errmsg;
+ }
+
+ if (obj) {
+ MP_TRACE_c(MP_FUNC, "found per-dir obj=0x%lx for %s.%s",
+ (unsigned long)obj,
+ info->modp->name, cmd->name);
+ }
+
+ /* XXX: could delay creation of srv_obj until
+ * Apache2::ModuleConfig->get is called.
+ */
+ srv_cfg = ap_get_module_config(s->module_config, info->modp);
+
+ if (srv_cfg) {
+ SV *srv_obj;
+ errmsg = modperl_module_config_create_obj(aTHX_ p, table, srv_cfg, info,
+ minfo->srv_create,
+ parms, &srv_obj);
+ if (errmsg) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return errmsg;
+ }
+
+ if (srv_obj) {
+ MP_TRACE_c(MP_FUNC, "found per-srv obj=0x%lx for %s.%s",
+ (unsigned long)srv_obj,
+ info->modp->name, cmd->name);
+ }
+ }
+
+ {
+ dSP;
+ ENTER;SAVETMPS;
+ PUSHMARK(SP);
+ EXTEND(SP, 2);
+
+ PUSHs(obj);
+ PUSHs(modperl_bless_cmd_parms(parms));
+
+ if (cmd->args_how != NO_ARGS) {
+ PUSH_STR_ARG(one);
+ PUSH_STR_ARG(two);
+ PUSH_STR_ARG(three);
+ }
+
+ PUTBACK;
+ count = call_method(info->func_name, G_EVAL|G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ SV *sv = POPs;
+ if (SvPOK(sv) && strEQ(SvPVX(sv), DECLINE_CMD)) {
+ retval = DECLINE_CMD;
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;LEAVE;
+ }
+
+ if (SvTRUE(ERRSV)) {
+ retval = SvPVX(ERRSV);
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+
+ if (modules_alias) {
+ MP_dSCFG(s);
+ /* unalias the temp aliasing */
+ scfg->modules = NULL;
+ }
+
+ return retval;
+}
+
+static const char *modperl_module_cmd_take1(cmd_parms *parms,
+ void *mconfig,
+ const char *one)
+{
+ return modperl_module_cmd_take123(parms, mconfig, one, NULL, NULL);
+}
+
+static const char *modperl_module_cmd_take2(cmd_parms *parms,
+ void *mconfig,
+ const char *one,
+ const char *two)
+{
+ return modperl_module_cmd_take123(parms, mconfig, one, two, NULL);
+}
+
+static const char *modperl_module_cmd_flag(cmd_parms *parms,
+ void *mconfig,
+ int flag)
+{
+ char buf[2];
+
+ apr_snprintf(buf, sizeof(buf), "%d", flag);
+
+ return modperl_module_cmd_take123(parms, mconfig, buf, NULL, NULL);
+}
+
+static const char *modperl_module_cmd_no_args(cmd_parms *parms,
+ void *mconfig)
+{
+ return modperl_module_cmd_take123(parms, mconfig, NULL, NULL, NULL);
+}
+
+#define modperl_module_cmd_raw_args modperl_module_cmd_take1
+#define modperl_module_cmd_iterate modperl_module_cmd_take1
+#define modperl_module_cmd_iterate2 modperl_module_cmd_take2
+#define modperl_module_cmd_take12 modperl_module_cmd_take2
+#define modperl_module_cmd_take23 modperl_module_cmd_take123
+#define modperl_module_cmd_take3 modperl_module_cmd_take123
+#define modperl_module_cmd_take13 modperl_module_cmd_take123
+
+#if defined(AP_HAVE_DESIGNATED_INITIALIZER)
+# define modperl_module_cmd_func_set(cmd, name) \
+ cmd->func.name = modperl_module_cmd_##name
+#else
+# define modperl_module_cmd_func_set(cmd, name) \
+ cmd->func = modperl_module_cmd_##name
+#endif
+
+static int modperl_module_cmd_lookup(command_rec *cmd)
+{
+ switch (cmd->args_how) {
+ case TAKE1:
+ case ITERATE:
+ modperl_module_cmd_func_set(cmd, take1);
+ break;
+ case TAKE2:
+ case ITERATE2:
+ case TAKE12:
+ modperl_module_cmd_func_set(cmd, take2);
+ break;
+ case TAKE3:
+ case TAKE23:
+ case TAKE123:
+ case TAKE13:
+ modperl_module_cmd_func_set(cmd, take3);
+ break;
+ case RAW_ARGS:
+ modperl_module_cmd_func_set(cmd, raw_args);
+ break;
+ case FLAG:
+ modperl_module_cmd_func_set(cmd, flag);
+ break;
+ case NO_ARGS:
+ modperl_module_cmd_func_set(cmd, no_args);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static apr_status_t modperl_module_remove(void *data)
+{
+ module *modp = (module *)data;
+
+ ap_remove_loaded_module(modp);
+
+ return APR_SUCCESS;
+}
+
+static const char *modperl_module_cmd_fetch(pTHX_ SV *obj,
+ const char *name, SV **retval)
+{
+ const char *errmsg = NULL;
+
+ if (*retval) {
+ SvREFCNT_dec(*retval);
+ *retval = (SV *)NULL;
+ }
+
+ if (sv_isobject(obj)) {
+ int count;
+ dSP;
+ ENTER;SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(obj);
+ PUTBACK;
+
+ count = call_method(name, G_EVAL|G_SCALAR);
+
+ SPAGAIN;
+
+ if (count == 1) {
+ SV *sv = POPs;
+ if (SvTRUE(sv)) {
+ *retval = SvREFCNT_inc(sv);
+ }
+ }
+
+ if (!*retval) {
+ errmsg = Perl_form(aTHX_ "%s->%s did not return a %svalue",
+ SvCLASS(obj), name, count ? "true " : "");
+ }
+
+ PUTBACK;
+ FREETMPS;LEAVE;
+
+ if (SvTRUE(ERRSV)) {
+ errmsg = SvPVX(ERRSV);
+ }
+ }
+ else if (SvROK(obj) && (SvTYPE(SvRV(obj)) == SVt_PVHV)) {
+ HV *hv = (HV*)SvRV(obj);
+ SV **svp = hv_fetch(hv, name, strlen(name), 0);
+
+ if (svp) {
+ *retval = SvREFCNT_inc(*svp);
+ }
+ else {
+ errmsg = Perl_form(aTHX_ "HASH key %s does not exist", name);
+ }
+ }
+ else {
+ errmsg = "command entry is not an object or a HASH reference";
+ }
+
+ return errmsg;
+}
+
+static const char *modperl_module_add_cmds(apr_pool_t *p, server_rec *s,
+ module *modp, SV *mod_cmds)
+{
+ const char *errmsg;
+ apr_array_header_t *cmds;
+ command_rec *cmd;
+ AV *module_cmds;
+ I32 i, fill;
+ MP_dINTERPa(NULL, NULL, s);
+ module_cmds = (AV*)SvRV(mod_cmds);
+
+ fill = AvFILL(module_cmds);
+ cmds = apr_array_make(p, fill+1, sizeof(command_rec));
+
+ for (i=0; i<=fill; i++) {
+ SV *val = (SV *)NULL;
+ STRLEN len;
+ SV *obj = AvARRAY(module_cmds)[i];
+ modperl_module_cmd_data_t *info = modperl_module_cmd_data_new(p);
+
+ info->modp = modp;
+
+ cmd = apr_array_push(cmds);
+
+ if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "name", &val))) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return errmsg;
+ }
+
+ cmd->name = apr_pstrdup(p, SvPV(val, len));
+
+ if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "args_how", &val))) {
+ /* XXX default based on $self->func prototype */
+ cmd->args_how = TAKE1; /* default */
+ }
+ else {
+ if (SvIOK(val)) {
+ cmd->args_how = SvIV(val);
+ }
+ else {
+ cmd->args_how =
+ SvIV(modperl_constants_lookup_apache2_const(aTHX_ SvPV(val, len)));
+ }
+ }
+
+ if (!modperl_module_cmd_lookup(cmd)) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return apr_psprintf(p,
+ "no command function defined for args_how=%d",
+ cmd->args_how);
+ }
+
+ if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "func", &val))) {
+ info->func_name = cmd->name; /* default */
+ }
+ else {
+ info->func_name = apr_pstrdup(p, SvPV(val, len));
+ }
+
+ if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "req_override", &val))) {
+ cmd->req_override = OR_ALL; /* default */
+ }
+ else {
+ if (SvIOK(val)) {
+ cmd->req_override = SvIV(val);
+ }
+ else {
+ cmd->req_override =
+ SvIV(modperl_constants_lookup_apache2_const(aTHX_ SvPV(val, len)));
+ }
+ }
+
+ if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "errmsg", &val))) {
+ /* default */
+ /* XXX generate help msg based on args_how */
+ cmd->errmsg = apr_pstrcat(p, cmd->name, " command", NULL);
+ }
+ else {
+ cmd->errmsg = apr_pstrdup(p, SvPV(val, len));
+ }
+
+ cmd->cmd_data = info;
+
+ /* no default if undefined */
+ if (!(errmsg = modperl_module_cmd_fetch(aTHX_ obj, "cmd_data", &val))) {
+ info->cmd_data = apr_pstrdup(p, SvPV(val, len));
+ }
+
+ if (val) {
+ SvREFCNT_dec(val);
+ val = (SV *)NULL;
+ }
+ }
+
+ cmd = apr_array_push(cmds);
+ cmd->name = NULL;
+
+ modp->cmds = (command_rec *)cmds->elts;
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return NULL;
+}
+
+static void modperl_module_insert(module *modp)
+{
+ /*
+ * insert after mod_perl, rather the top of the list.
+ * (see ap_add_module; does not insert into ap_top_module list if
+ * m->next != NULL)
+ * this way, modperl config merging happens before this module.
+ */
+
+ modp->next = perl_module.next;
+ perl_module.next = modp;
+}
+
+#define MP_isGV(gv) (gv && isGV(gv))
+
+static modperl_mgv_t *modperl_module_fetch_method(pTHX_
+ apr_pool_t *p,
+ module *modp,
+ const char *method)
+{
+ modperl_mgv_t *mgv;
+
+ HV *stash = gv_stashpv(modp->name, FALSE);
+ GV *gv = gv_fetchmethod_autoload(stash, method, FALSE);
+
+ MP_TRACE_c(MP_FUNC, "looking for method %s in package `%s'...%sfound",
+ method, modp->name,
+ MP_isGV(gv) ? "" : "not ");
+
+ if (!MP_isGV(gv)) {
+ return NULL;
+ }
+
+ mgv = modperl_mgv_compile(aTHX_ p,
+ apr_pstrcat(p,
+ modp->name, "::", method, NULL));
+
+ return mgv;
+}
+
+const char *modperl_module_add(apr_pool_t *p, server_rec *s,
+ const char *name, SV *mod_cmds)
+{
+ MP_dSCFG(s);
+ const char *errmsg;
+ module *modp;
+ modperl_module_info_t *minfo;
+ MP_dINTERPa(NULL, NULL, s);
+ modp = (module *)apr_pcalloc(p, sizeof(*modp));
+ minfo = (modperl_module_info_t *)apr_pcalloc(p, sizeof(*minfo));
+
+ /* STANDARD20_MODULE_STUFF */
+ modp->version = MODULE_MAGIC_NUMBER_MAJOR;
+ modp->minor_version = MODULE_MAGIC_NUMBER_MINOR;
+ modp->module_index = -1;
+ modp->name = apr_pstrdup(p, name);
+ modp->magic = MODULE_MAGIC_COOKIE;
+
+ /* use this slot for our context */
+ modp->dynamic_load_handle = minfo;
+
+ /*
+ * XXX: we should lookup here if the Perl methods exist,
+ * and set these pointers only if they do.
+ */
+ modp->create_dir_config = modperl_module_config_dir_create;
+ modp->merge_dir_config = modperl_module_config_dir_merge;
+ modp->create_server_config = modperl_module_config_srv_create;
+ modp->merge_server_config = modperl_module_config_srv_merge;
+
+ minfo->namelen = strlen(name);
+
+ minfo->dir_create =
+ modperl_module_fetch_method(aTHX_ p, modp, "DIR_CREATE");
+
+ minfo->dir_merge =
+ modperl_module_fetch_method(aTHX_ p, modp, "DIR_MERGE");
+
+ minfo->srv_create =
+ modperl_module_fetch_method(aTHX_ p, modp, "SERVER_CREATE");
+
+ minfo->srv_merge =
+ modperl_module_fetch_method(aTHX_ p, modp, "SERVER_MERGE");
+
+ modp->cmds = NULL;
+
+ if ((errmsg = modperl_module_add_cmds(p, s, modp, mod_cmds))) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return errmsg;
+ }
+
+ modperl_module_insert(modp);
+
+ mp_add_loaded_module(modp, p, modp->name);
+
+ apr_pool_cleanup_register(p, modp, modperl_module_remove,
+ apr_pool_cleanup_null);
+
+ ap_single_module_configure(p, s, modp);
+
+ if (!scfg->modules) {
+ scfg->modules = apr_hash_make(p);
+ }
+
+ apr_hash_set(scfg->modules, apr_pstrdup(p, name), APR_HASH_KEY_STRING, modp);
+
+#ifdef USE_ITHREADS
+ /*
+ * if the Perl module is loaded in the base server and a vhost
+ * has configuration directives from that module, but no mod_perl.c
+ * directives, scfg == NULL when modperl_module_cmd_take123 is run.
+ * this happens before server configs are merged, so we stash a pointer
+ * to what will be merged as the parent interp later. i.e. "safe hack"
+ */
+ if (!modperl_interp_pool_get(p)) {
+ /* for vhosts */
+ MP_TRACE_i(MP_FUNC, "set interp 0x%lx in pconf pool 0x%lx",
+ (unsigned long)scfg->mip->parent, (unsigned long)p);
+ modperl_interp_pool_set(p, scfg->mip->parent);
+ }
+#endif
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return NULL;
+}
+
+SV *modperl_module_config_get_obj(pTHX_ SV *pmodule, server_rec *s,
+ ap_conf_vector_t *v)
+{
+ MP_dSCFG(s);
+ module *modp;
+ const char *name;
+ void *ptr;
+ PTR_TBL_t *table;
+ SV *obj;
+
+ if (!v) {
+ v = s->module_config;
+ }
+
+ if (SvROK(pmodule)) {
+ name = SvCLASS(pmodule);
+ }
+ else {
+ STRLEN n_a;
+ name = SvPV(pmodule, n_a);
+ }
+
+ if (!(scfg->modules &&
+ (modp = apr_hash_get(scfg->modules, name, APR_HASH_KEY_STRING)))) {
+ return &PL_sv_undef;
+ }
+
+ if (!(ptr = ap_get_module_config(v, modp))) {
+ return &PL_sv_undef;
+ }
+
+ if (!(table = modperl_module_config_table_get(aTHX_ FALSE))) {
+ return &PL_sv_undef;
+ }
+
+ if (!(obj = modperl_svptr_table_fetch(aTHX_ table, ptr))) {
+ return &PL_sv_undef;
+ }
+
+ return obj;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_module.h b/2_0_13/src/modules/perl/modperl_module.h
new file mode 100644
index 0000000..41e8312
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_module.h
@@ -0,0 +1,37 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_MODULE_H
+#define MODPERL_MODULE_H
+
+PTR_TBL_t *modperl_module_config_table_get(pTHX_ int create);
+
+void modperl_module_config_table_set(pTHX_ PTR_TBL_t *table);
+
+const char *modperl_module_add(apr_pool_t *p, server_rec *s,
+ const char *name, SV *mod_cmds);
+
+SV *modperl_module_config_get_obj(pTHX_ SV *pmodule, server_rec *s,
+ ap_conf_vector_t *v);
+
+#endif /* MODPERL_MODULE_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_options.c b/2_0_13/src/modules/perl/modperl_options.c
new file mode 100644
index 0000000..5077ec4
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_options.c
@@ -0,0 +1,157 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* re-use the ->unset field to determine options type */
+#define MpOptionsType(o) (o)->unset
+#define MpOptionsTypeDir(o) MpOptionsType(o) == MpDir_f_UNSET
+#define MpOptionsTypeSrv(o) MpOptionsType(o) == MpSrv_f_UNSET
+#define MpOptionsTypeDir_set(o) MpOptionsType(o) = MpDir_f_UNSET
+#define MpOptionsTypeSrv_set(o) MpOptionsType(o) = MpSrv_f_UNSET
+#define MP_OPTIONS_TYPE_DIR MpDir_f_UNSET
+#define MP_OPTIONS_TYPE_SRV MpSrv_f_UNSET
+
+static modperl_opts_t flags_lookup(modperl_options_t *o,
+ const char *str)
+{
+ switch (MpOptionsType(o)) {
+ case MP_OPTIONS_TYPE_SRV:
+ return modperl_flags_lookup_srv(str);
+ case MP_OPTIONS_TYPE_DIR:
+ return modperl_flags_lookup_dir(str);
+ default:
+ return '\0';
+ };
+}
+
+static const char *type_lookup(modperl_options_t *o)
+{
+ switch (MpOptionsType(o)) {
+ case MP_OPTIONS_TYPE_SRV:
+ return "server";
+ case MP_OPTIONS_TYPE_DIR:
+ return "directory";
+ default:
+ return "unknown";
+ };
+}
+
+modperl_options_t *modperl_options_new(apr_pool_t *p, int type)
+{
+ modperl_options_t *options =
+ (modperl_options_t *)apr_pcalloc(p, sizeof(*options));
+
+ options->opts = options->unset =
+ (type == MpSrvType ? MpSrv_f_UNSET : MpDir_f_UNSET);
+
+ return options;
+}
+
+const char *modperl_options_set(apr_pool_t *p, modperl_options_t *o,
+ const char *str)
+{
+ modperl_opts_t opt;
+ char action = '\0';
+ const char *error = NULL;
+
+ if (*str == '+' || *str == '-') {
+ action = *(str++);
+ }
+
+ if ((opt = flags_lookup(o, str)) == -1) {
+ error = apr_pstrcat(p, "Invalid per-", type_lookup(o),
+ " PerlOption: ", str, NULL);
+
+ if (MpOptionsTypeDir(o)) {
+ modperl_options_t dummy;
+ MpOptionsTypeSrv_set(&dummy);
+
+ if (flags_lookup(&dummy, str) == -1) {
+ error = apr_pstrcat(p, error,
+ " (only allowed per-server)",
+ NULL);
+ }
+ }
+
+ return error;
+ }
+#ifndef USE_ITHREADS
+ else if (MpOptionsTypeSrv(o)) {
+ if (MpSrvOPT_ITHREAD_ONLY(opt)) {
+ return apr_pstrcat(p, "PerlOption `", str,
+ "' requires an ithreads enabled Perl", NULL);
+ }
+ }
+#endif
+
+ o->opts_seen |= opt;
+
+ if (action == '-') {
+ o->opts_remove |= opt;
+ o->opts_add &= ~opt;
+ o->opts &= ~opt;
+ }
+ else if (action == '+') {
+ o->opts_add |= opt;
+ o->opts_remove &= ~opt;
+ o->opts |= opt;
+ }
+ else {
+ o->opts |= opt;
+ }
+
+ return NULL;
+}
+
+modperl_options_t *modperl_options_merge(apr_pool_t *p,
+ modperl_options_t *base,
+ modperl_options_t *add)
+{
+ modperl_options_t *conf = modperl_options_new(p, 0);
+ memcpy((char *)conf, (const char *)base, sizeof(*base));
+
+ if (add->opts & add->unset) {
+ /* there was no explicit setting of add->opts, so we merge
+ * preserve the invariant (opts_add & opts_remove) == 0
+ */
+ conf->opts_add =
+ (conf->opts_add & ~add->opts_remove) | add->opts_add;
+ conf->opts_remove =
+ (conf->opts_remove & ~add->opts_add) | add->opts_remove;
+ conf->opts =
+ (conf->opts & ~conf->opts_remove) | conf->opts_add;
+ }
+ else {
+ /* otherwise we just copy, because an explicit opts setting
+ * overrides all earlier +/- modifiers
+ */
+ conf->opts = add->opts;
+ conf->opts_add = add->opts_add;
+ conf->opts_remove = add->opts_remove;
+ }
+
+ conf->opts_seen |= add->opts_seen;
+
+ return conf;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_options.h b/2_0_13/src/modules/perl/modperl_options.h
new file mode 100644
index 0000000..62d23da
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_options.h
@@ -0,0 +1,36 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_OPTIONS_H
+#define MODPERL_OPTIONS_H
+
+modperl_options_t *modperl_options_new(apr_pool_t *p, int type);
+
+const char *modperl_options_set(apr_pool_t *p, modperl_options_t *o,
+ const char *s);
+
+modperl_options_t *modperl_options_merge(apr_pool_t *p,
+ modperl_options_t *base,
+ modperl_options_t *new);
+
+#endif /* MODPERL_OPTIONS_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_pcw.c b/2_0_13/src/modules/perl/modperl_pcw.c
new file mode 100644
index 0000000..0c247b0
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_pcw.c
@@ -0,0 +1,149 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/*
+ * pcw == Parsed Config Walker
+ * generic functions for walking parsed config using callbacks
+ */
+
+void ap_pcw_walk_location_config(apr_pool_t *pconf, server_rec *s,
+ core_server_config *sconf,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data)
+{
+ int i;
+ ap_conf_vector_t **urls;
+
+ if( !sconf->sec_url ) return;
+
+ urls = (ap_conf_vector_t **)sconf->sec_url->elts;
+
+ for (i = 0; i < sconf->sec_url->nelts; i++) {
+ core_dir_config *conf =
+ ap_get_module_config(urls[i], &core_module);
+ void *dir_cfg = ap_get_module_config(urls[i], modp);
+
+ if (!dir_cb(pconf, s, dir_cfg, conf->d, data)) {
+ break;
+ }
+ }
+}
+
+void ap_pcw_walk_directory_config(apr_pool_t *pconf, server_rec *s,
+ core_server_config *sconf,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data)
+{
+ int i;
+ ap_conf_vector_t **dirs;
+
+ if( !sconf->sec_dir ) return;
+
+ dirs = (ap_conf_vector_t **)sconf->sec_dir->elts;
+
+ for (i = 0; i < sconf->sec_dir->nelts; i++) {
+ core_dir_config *conf =
+ ap_get_module_config(dirs[i], &core_module);
+ void *dir_cfg = ap_get_module_config(dirs[i], modp);
+
+ if (!dir_cb(pconf, s, dir_cfg, conf->d, data)) {
+ break;
+ }
+ }
+}
+
+void ap_pcw_walk_files_config(apr_pool_t *pconf, server_rec *s,
+ core_dir_config *dconf,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data)
+{
+ int i;
+ ap_conf_vector_t **dirs;
+
+ if( !dconf->sec_file ) return;
+
+ dirs = (ap_conf_vector_t **)dconf->sec_file->elts;
+
+ for (i = 0; i < dconf->sec_file->nelts; i++) {
+ core_dir_config *conf =
+ ap_get_module_config(dirs[i], &core_module);
+ void *dir_cfg = ap_get_module_config(dirs[i], modp);
+
+ if (!dir_cb(pconf, s, dir_cfg, conf->d, data)) {
+ break;
+ }
+ }
+}
+
+void ap_pcw_walk_default_config(apr_pool_t *pconf, server_rec *s,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data)
+{
+ core_dir_config *conf =
+ ap_get_module_config(s->lookup_defaults, &core_module);
+ void *dir_cfg =
+ ap_get_module_config(s->lookup_defaults, modp);
+
+ dir_cb(pconf, s, dir_cfg, conf->d, data);
+}
+
+void ap_pcw_walk_server_config(apr_pool_t *pconf, server_rec *s,
+ module *modp,
+ ap_pcw_srv_cb_t srv_cb, void *data)
+{
+ void *cfg = ap_get_module_config(s->module_config, modp);
+
+ if (!cfg) {
+ return;
+ }
+
+ srv_cb(pconf, s, cfg, data);
+}
+
+void ap_pcw_walk_config(apr_pool_t *pconf, server_rec *s,
+ module *modp, void *data,
+ ap_pcw_dir_cb_t dir_cb, ap_pcw_srv_cb_t srv_cb)
+{
+ for (; s; s = s->next) {
+ core_dir_config *dconf =
+ ap_get_module_config(s->lookup_defaults,
+ &core_module);
+
+ core_server_config *sconf =
+ ap_get_module_config(s->module_config,
+ &core_module);
+
+ if (dir_cb) {
+ ap_pcw_walk_location_config(pconf, s, sconf, modp, dir_cb, data);
+ ap_pcw_walk_directory_config(pconf, s, sconf, modp, dir_cb, data);
+ ap_pcw_walk_files_config(pconf, s, dconf, modp, dir_cb, data);
+ ap_pcw_walk_default_config(pconf, s, modp, dir_cb, data);
+ }
+
+ if (srv_cb) {
+ ap_pcw_walk_server_config(pconf, s, modp, srv_cb, data);
+ }
+ }
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_pcw.h b/2_0_13/src/modules/perl/modperl_pcw.h
new file mode 100644
index 0000000..4e97acf
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_pcw.h
@@ -0,0 +1,60 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_PCW_H
+#define MODPERL_PCW_H
+
+typedef int (*ap_pcw_dir_cb_t) (apr_pool_t *, server_rec *,
+ void *, char *, void *);
+
+typedef int (*ap_pcw_srv_cb_t) (apr_pool_t *, server_rec *,
+ void *, void *);
+
+void ap_pcw_walk_location_config(apr_pool_t *pconf, server_rec *s,
+ core_server_config *sconf,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data);
+
+void ap_pcw_walk_directory_config(apr_pool_t *pconf, server_rec *s,
+ core_server_config *sconf,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data);
+
+void ap_pcw_walk_files_config(apr_pool_t *pconf, server_rec *s,
+ core_dir_config *dconf,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data);
+
+void ap_pcw_walk_default_config(apr_pool_t *pconf, server_rec *s,
+ module *modp,
+ ap_pcw_dir_cb_t dir_cb, void *data);
+
+void ap_pcw_walk_server_config(apr_pool_t *pconf, server_rec *s,
+ module *modp,
+ ap_pcw_srv_cb_t srv_cb, void *data);
+
+void ap_pcw_walk_config(apr_pool_t *pconf, server_rec *s,
+ module *modp, void *data,
+ ap_pcw_dir_cb_t dir_cb, ap_pcw_srv_cb_t srv_cb);
+
+#endif /* MODPERL_PCW_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl.c b/2_0_13/src/modules/perl/modperl_perl.c
new file mode 100644
index 0000000..9ec744f
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl.c
@@ -0,0 +1,291 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* this module contains mod_perl small tweaks to the Perl runtime
+ * others (larger tweaks) are in their own modules, e.g. modperl_env.c
+ */
+
+typedef struct {
+ const char *name;
+ const char *sub_name;
+ const char *core_name;
+} modperl_perl_core_global_t;
+
+#define MP_PERL_CORE_GLOBAL_ENT(name) \
+{ name, "ModPerl::Util::" name, "CORE::GLOBAL::" name }
+
+static modperl_perl_core_global_t MP_perl_core_global_entries[] = {
+ MP_PERL_CORE_GLOBAL_ENT("exit"),
+ { NULL },
+};
+
+XS(XS_ModPerl__Util_exit); /* prototype to pass -Wmissing-prototypes */
+XS(XS_ModPerl__Util_exit)
+{
+ dXSARGS;
+ int status;
+ if (items < 0 || items > 1) {
+ Perl_croak(aTHX_ "Usage: ModPerl::Util::exit(status=0)");
+ }
+ /* default: 0 */
+ status = items < 1 ? 0 : (int)SvIV(ST(0));
+ modperl_perl_exit(aTHX_ status);
+
+ XSRETURN_EMPTY;
+}
+
+void modperl_perl_core_global_init(pTHX)
+{
+ modperl_perl_core_global_t *cglobals = MP_perl_core_global_entries;
+
+ while (cglobals->name) {
+ GV *gv = gv_fetchpv(cglobals->core_name, TRUE, SVt_PVCV);
+#ifdef MUTABLE_CV
+ GvCV_set(gv,
+ MUTABLE_CV(SvREFCNT_inc(get_cv(cglobals->sub_name, TRUE))));
+#else
+ GvCV_set(gv,
+ (CV*)(SvREFCNT_inc(get_cv(cglobals->sub_name, TRUE))));
+#endif
+ GvIMPORTED_CV_on(gv);
+ cglobals++;
+ }
+
+ newXS("ModPerl::Util::exit", XS_ModPerl__Util_exit, __FILE__);
+}
+
+static void modperl_perl_ids_get(modperl_perl_ids_t *ids)
+{
+ ids->pid = (I32)getpid();
+#ifdef MP_MAINTAIN_PPID
+ ids->ppid = (I32)getppid();
+#endif
+#ifndef WIN32
+ ids->uid = getuid();
+ ids->euid = geteuid();
+ ids->gid = getgid();
+ ids->egid = getegid();
+
+ MP_TRACE_r(MP_FUNC,
+ "pid=%d, "
+#ifdef MP_MAINTAIN_PPID
+ "ppid=%d, "
+#endif
+ "uid=%" Uid_t_f ", euid=%" Uid_t_f ", "
+ "gid=%" Gid_t_f ", egid=%" Gid_t_f,
+ (int)ids->pid,
+#ifdef MP_MAINTAIN_PPID
+ (int)ids->ppid,
+#endif
+ ids->uid, ids->euid,
+ ids->gid, ids->egid);
+#endif /* #ifndef WIN32 */
+}
+
+static void modperl_perl_init_ids(pTHX_ modperl_perl_ids_t *ids)
+{
+ sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), ids->pid);
+
+#if !MP_PERL_VERSION_AT_LEAST(5, 16, 0)
+#ifndef WIN32
+ PL_uid = ids->uid;
+ PL_euid = ids->euid;
+ PL_gid = ids->gid;
+ PL_egid = ids->egid;
+#endif
+#ifdef MP_MAINTAIN_PPID
+ PL_ppid = ids->ppid;
+#endif
+#endif
+}
+
+
+#ifdef USE_ITHREADS
+
+static apr_status_t modperl_perl_init_ids_mip(pTHX_ modperl_interp_pool_t *mip,
+ void *data)
+{
+ modperl_perl_init_ids(aTHX_ (modperl_perl_ids_t *)data);
+ return APR_SUCCESS;
+}
+
+#endif /* USE_ITHREADS */
+
+void modperl_perl_init_ids_server(server_rec *s)
+{
+ modperl_perl_ids_t ids;
+ modperl_perl_ids_get(&ids);
+#ifdef USE_ITHREADS
+ modperl_interp_mip_walk_servers(NULL, s,
+ modperl_perl_init_ids_mip,
+ (void*)&ids);
+#else
+ modperl_perl_init_ids(aTHX_ &ids);
+#endif
+}
+
+void modperl_perl_destruct(PerlInterpreter *perl)
+{
+ char **orig_environ = NULL;
+ PTR_TBL_t *module_commands;
+ dTHXa(perl);
+
+ PERL_SET_CONTEXT(perl);
+
+ modperl_perl_call_endav(aTHX);
+
+ PL_perl_destruct_level = modperl_perl_destruct_level();
+
+#ifdef USE_ENVIRON_ARRAY
+ /* XXX: otherwise Perl may try to free() environ multiple times
+ * but it wasn't Perl that modified environ
+ * at least, not if modperl is doing things right
+ * this is a bug in Perl.
+ */
+# ifdef WIN32
+ /*
+ * PL_origenviron = environ; doesn't work under win32 service.
+ * we pull a different stunt here that has the same effect of
+ * tricking perl into _not_ freeing the real 'environ' array.
+ * instead temporarily swap with a dummy array we malloc
+ * here which is ok to let perl free.
+ */
+ orig_environ = environ;
+ environ = safemalloc(2 * sizeof(char *));
+ environ[0] = NULL;
+# else
+ PL_origenviron = environ;
+# endif
+#endif
+
+ {
+ dTHXa(perl);
+
+ if ((module_commands = modperl_module_config_table_get(aTHX_ FALSE))) {
+ modperl_svptr_table_destroy(aTHX_ module_commands);
+ }
+ }
+
+ modperl_env_unload(aTHX);
+
+ perl_destruct(perl);
+
+ /* XXX: big bug in 5.6.1 fixed in 5.7.2+
+ * XXX: try to find a workaround for 5.6.1
+ */
+#if defined(WIN32) && !defined(CLONEf_CLONE_HOST)
+# define MP_NO_PERL_FREE
+#endif
+
+#ifndef MP_NO_PERL_FREE
+ perl_free(perl);
+#endif
+
+#ifdef USE_ENVIRON_ARRAY
+ if (orig_environ) {
+ environ = orig_environ;
+ }
+#endif
+}
+
+void modperl_perl_call_endav(pTHX)
+{
+ if (PL_endav) {
+ modperl_perl_call_list(aTHX_ PL_endav, "END");
+ }
+}
+
+#if !(MP_PERL_VERSION_AT_MOST(5, 8, 0)) && \
+ (defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT))
+#define MP_NEED_HASH_SEED_FIXUP
+#endif
+
+#ifdef MP_NEED_HASH_SEED_FIXUP
+static UV MP_init_hash_seed = 0;
+static bool MP_init_hash_seed_set = FALSE;
+#endif
+
+/* see modperl_hash_seed_set() */
+void modperl_hash_seed_init(apr_pool_t *p)
+{
+#ifdef MP_NEED_HASH_SEED_FIXUP
+ char *s;
+ /* check if there is a specific hash seed passed via the env var
+ * and if that's the case -- use it */
+ apr_status_t rv = apr_env_get(&s, "PERL_HASH_SEED", p);
+ if (rv == APR_SUCCESS) {
+ if (s) {
+ while (isSPACE(*s)) s++;
+ }
+ if (s && isDIGIT(*s)) {
+ MP_init_hash_seed = (UV)Atol(s); /* XXX: Atoul()? */
+ MP_init_hash_seed_set = TRUE;
+ }
+ }
+
+ /* calculate our own random hash seed */
+ if (!MP_init_hash_seed_set) {
+ apr_uuid_t *uuid = (apr_uuid_t *)apr_palloc(p, sizeof(apr_uuid_t));
+ char buf[APR_UUID_FORMATTED_LENGTH + 1];
+ int i;
+
+ apr_initialize();
+ apr_uuid_get(uuid);
+ apr_uuid_format(buf, uuid);
+ /* fprintf(stderr, "UUID: %s\n", buf); */
+
+ /* XXX: need a better alg to convert uuid string into a seed */
+ for (i=0; buf[i]; i++){
+ MP_init_hash_seed += (UV)(i+1)*(buf[i]+MP_init_hash_seed);
+ }
+
+ MP_init_hash_seed_set = TRUE;
+ }
+#endif
+}
+
+/* before 5.8.1, perl was using HASH_SEED=0, starting from 5.8.1
+ * it randomizes if perl was compiled with ccflags -DUSE_HASH_SEED
+ * or -DUSE_HASH_SEED_EXPLICIT, in which case we need to tell perl
+ * to use the same seed everywhere */
+void modperl_hash_seed_set(pTHX)
+{
+#ifdef MP_NEED_HASH_SEED_FIXUP
+ if (MP_init_hash_seed_set) {
+#if MP_PERL_VERSION_AT_LEAST(5, 17, 6)
+ memcpy(PL_hash_seed, &MP_init_hash_seed,
+ sizeof(PL_hash_seed) > sizeof(MP_init_hash_seed) ?
+ sizeof(MP_init_hash_seed) : sizeof(PL_hash_seed));
+ PL_hash_seed_set = MP_init_hash_seed_set;
+#elif MP_PERL_VERSION_AT_LEAST(5, 8, 2)
+ PL_rehash_seed = MP_init_hash_seed;
+ PL_rehash_seed_set = MP_init_hash_seed_set;
+#else
+ PL_hash_seed = MP_init_hash_seed;
+ PL_hash_seed_set = MP_init_hash_seed_set;
+#endif
+ }
+#endif
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl.h b/2_0_13/src/modules/perl/modperl_perl.h
new file mode 100644
index 0000000..d91ab5f
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl.h
@@ -0,0 +1,71 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_PERL_H
+#define MODPERL_PERL_H
+
+/* starting from 5.8.1 perl caches ppids, so we need to maintain our
+ * own. some distros fetch fake 5.8.0 with changes from 5.8.1, so we
+ * need to do that for those fake 5.8.0 as well. real 5.8.0 doesn't
+ * have THREADS_HAVE_PIDS defined.
+ */
+#if MP_PERL_VERSION_AT_LEAST(5, 8, 0) && THREADS_HAVE_PIDS
+#define MP_MAINTAIN_PPID
+#endif
+
+typedef struct {
+ I32 pid;
+ Uid_t uid, euid;
+ Gid_t gid, egid;
+#ifdef MP_MAINTAIN_PPID
+ Uid_t ppid;
+#endif
+} modperl_perl_ids_t;
+
+void modperl_perl_core_global_init(pTHX);
+
+void modperl_perl_init_ids_server(server_rec *s);
+
+void modperl_perl_destruct(PerlInterpreter *perl);
+
+void modperl_perl_call_endav(pTHX);
+
+void modperl_hash_seed_init(apr_pool_t *p);
+
+void modperl_hash_seed_set(pTHX);
+
+#ifndef GvCV_set
+# define GvCV_set(gv, cv) (GvCV(gv)=(cv))
+#endif
+#ifndef GvGP_set
+# define GvGP_set(gv, gp) (GvGP(gv)=(gp))
+#endif
+
+#ifndef Newx
+# define Newx(v,n,t) New(0,v,n,t)
+#endif
+#ifndef Newxz
+# define Newxz(v,n,t) Newz(0,v,n,t)
+#endif
+
+#endif /* MODPERL_PERL_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl_global.c b/2_0_13/src/modules/perl/modperl_perl_global.c
new file mode 100644
index 0000000..f52e42c
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl_global.c
@@ -0,0 +1,503 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* XXX: PL_modglobal thingers might be useful elsewhere */
+
+#define MP_MODGLOBAL_ENT(key) \
+ {key, "ModPerl::" key, MP_SSTRLEN("ModPerl::") + MP_SSTRLEN(key), 0}
+
+static modperl_modglobal_key_t MP_modglobal_keys[] = {
+ MP_MODGLOBAL_ENT("END"),
+ MP_MODGLOBAL_ENT("ANONSUB"),
+ { NULL },
+};
+
+void modperl_modglobal_hash_keys(pTHX)
+{
+ modperl_modglobal_key_t *gkey = MP_modglobal_keys;
+
+ while (gkey->name) {
+ PERL_HASH(gkey->hash, gkey->val, gkey->len);
+ gkey++;
+ }
+}
+
+modperl_modglobal_key_t *modperl_modglobal_lookup(pTHX_ const char *name)
+{
+ modperl_modglobal_key_t *gkey = MP_modglobal_keys;
+
+ while (gkey->name) {
+ if (strEQ(gkey->name, name)) {
+ return gkey;
+ }
+ gkey++;
+ }
+
+ return NULL;
+}
+
+static void modperl_perl_global_init(pTHX_ modperl_perl_globals_t *globals)
+{
+ globals->env.gv = PL_envgv;
+ globals->inc.gv = PL_incgv;
+ globals->defout.gv = PL_defoutgv;
+ globals->rs.sv = &PL_rs;
+ globals->end.av = &PL_endav;
+ globals->end.key = MP_MODGLOBAL_END;
+}
+
+/*
+ * if (exists $PL_modglobal{$key}{$package}) {
+ * return $PL_modglobal{$key}{$package};
+ * }
+ * elsif ($autovivify) {
+ * return $PL_modglobal{$key}{$package} = [];
+ * }
+ * else {
+ * return (AV *)NULL; # a null pointer in C of course :)
+ * }
+ */
+static AV *modperl_perl_global_avcv_fetch(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen,
+ I32 autovivify)
+{
+ HE *he = MP_MODGLOBAL_FETCH(gkey);
+ HV *hv;
+
+ if (!(he && (hv = (HV*)HeVAL(he)))) {
+ if (autovivify) {
+ hv = MP_MODGLOBAL_STORE_HV(gkey);
+ }
+ else {
+ return (AV *)NULL;
+ }
+ }
+
+ if ((he = hv_fetch_he(hv, (char *)package, packlen, 0))) {
+ return (AV*)HeVAL(he);
+ }
+ else {
+ if (autovivify) {
+ return (AV*)*hv_store(hv, package, packlen, (SV*)newAV(), 0);
+ }
+ else {
+ return (AV *)NULL;
+ }
+ }
+}
+
+/* autovivify $PL_modglobal{$key}{$package} if it doesn't exist yet,
+ * so that in modperl_perl_global_avcv_set we will know whether to
+ * store blocks in it or keep them in the original list.
+ *
+ * For example in the case of END blocks, if
+ * $PL_modglobal{END}{$package} exists, modperl_perl_global_avcv_set
+ * will push newly encountered END blocks to it, otherwise it'll keep
+ * them in PL_endav.
+ */
+void modperl_perl_global_avcv_register(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen)
+{
+ AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey,
+ package, packlen, TRUE);
+
+ MP_TRACE_g(MP_FUNC, "register PL_modglobal %s::%s (has %d entries)",
+ package, (char*)gkey->name, av ? 1+av_len(av) : 0);
+}
+
+/* if (exists $PL_modglobal{$key}{$package}) {
+ * for my $cv (@{ $PL_modglobal{$key}{$package} }) {
+ * $cv->();
+ * }
+ * }
+ */
+void modperl_perl_global_avcv_call(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen)
+{
+ AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen,
+ FALSE);
+
+ MP_TRACE_g(MP_FUNC, "run PL_modglobal %s::%s (has %d entries)",
+ package, (char*)gkey->name, av ? 1+av_len(av) : 0);
+
+ if (av) {
+ modperl_perl_call_list(aTHX_ av, gkey->name);
+ }
+}
+
+
+/* if (exists $PL_modglobal{$key}{$package}) {
+ * @{ $PL_modglobal{$key}{$package} } = ();
+ * }
+ */
+void modperl_perl_global_avcv_clear(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen)
+{
+ AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey,
+ package, packlen, FALSE);
+
+ MP_TRACE_g(MP_FUNC, "clear PL_modglobal %s::%s (has %d entries)",
+ package, (char*)gkey->name, av ? 1+av_len(av) : 0);
+
+ if (av) {
+ av_clear(av);
+ }
+}
+
+static int modperl_perl_global_avcv_set(pTHX_ SV *sv, MAGIC *mg)
+{
+ AV *mav, *av = (AV*)sv;
+ const char *package = HvNAME(PL_curstash);
+ I32 packlen = strlen(package);
+ modperl_modglobal_key_t *gkey =
+ (modperl_modglobal_key_t *)mg->mg_ptr;
+
+ /* the argument sv, is the original list perl was operating on.
+ * (e.g. PL_endav). So now if we find that we have package/cv name
+ * (e.g. Foo/END) registered for set-aside, we remove the cv that
+ * was just unshifted in and push it into
+ * $PL_modglobal{$key}{$package}. Otherwise we do nothing, which
+ * keeps the unshifted cv (e.g. END block) in its original av
+ * (e.g. PL_endav)
+ */
+
+ mav = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen, FALSE);
+
+ if (!mav) {
+ MP_TRACE_g(MP_FUNC, "%s::%s is not going to PL_modglobal",
+ package, (char*)gkey->name);
+ /* keep it in the tied list (e.g. PL_endav) */
+ return 1;
+ }
+
+ MP_TRACE_g(MP_FUNC, "%s::%s is going into PL_modglobal",
+ package, (char*)gkey->name);
+
+ sv = av_shift(av);
+
+ /* push @{ $PL_modglobal{$key}{$package} }, $cv */
+ av_store(mav, AvFILLp(mav)+1, sv);
+
+ /* print scalar @{ $PL_modglobal{$key}{$package} } */
+ MP_TRACE_g(MP_FUNC, "%s::%s av now has %d entries",
+ package, (char*)gkey->name, 1+av_len(mav));
+
+ return 1;
+}
+
+static MGVTBL modperl_vtbl_global_avcv_t = {
+ 0,
+ modperl_perl_global_avcv_set,
+ 0, 0, 0,
+};
+
+static void modperl_perl_global_avcv_tie(pTHX_ modperl_modglobal_key_e key,
+ AV *av)
+{
+ if (!SvMAGIC((SV*)av)) {
+ MAGIC *mg;
+ Newxz(mg, 1, MAGIC);
+ mg->mg_virtual = &modperl_vtbl_global_avcv_t;
+ mg->mg_ptr = (char *)&MP_modglobal_keys[key];
+ mg->mg_len = -1; /* prevent free() of mg->mg_ptr */
+ SvMAGIC((SV*)av) = mg;
+ }
+
+ SvSMAGICAL_on((SV*)av);
+}
+
+static void modperl_perl_global_avcv_untie(pTHX_ AV *av)
+{
+ SvSMAGICAL_off((SV*)av);
+}
+
+static void
+modperl_perl_global_avcv_save(pTHX_ modperl_perl_global_avcv_t *avcv)
+{
+ if (!*avcv->av) {
+ *avcv->av = newAV();
+ }
+
+ modperl_perl_global_avcv_tie(aTHX_ avcv->key, *avcv->av);
+}
+
+static void
+modperl_perl_global_avcv_restore(pTHX_ modperl_perl_global_avcv_t *avcv)
+{
+ modperl_perl_global_avcv_untie(aTHX_ *avcv->av);
+}
+
+/*
+ * newHVhv is not good enough since it does not copy magic.
+ * XXX: 5.8.0+ newHVhv has some code thats faster than hv_iternext
+ */
+static HV *copyENV(pTHX_ HV *ohv)
+{
+ HE *entry, *hv_eiter;
+ I32 hv_riter;
+ register HV *hv;
+ STRLEN hv_max = HvMAX(ohv);
+ STRLEN hv_fill = HvFILL(ohv);
+
+ hv = newHV();
+ while (hv_max && hv_max + 1 >= hv_fill * 2) {
+ hv_max = hv_max / 2; /* Is always 2^n-1 */
+ }
+
+ HvMAX(hv) = hv_max;
+
+ if (!hv_fill) {
+ return hv;
+ }
+
+ hv_riter = HvRITER(ohv); /* current root of iterator */
+ hv_eiter = HvEITER(ohv); /* current entry of iterator */
+
+ hv_iterinit(ohv);
+ while ((entry = hv_iternext(ohv))) {
+ SV *sv = newSVsv(HeVAL(entry));
+ modperl_envelem_tie(sv, HeKEY(entry), HeKLEN(entry));
+ (void)hv_store(hv, HeKEY(entry), HeKLEN(entry),
+ sv, HeHASH(entry));
+ }
+
+ HvRITER(ohv) = hv_riter;
+ HvEITER(ohv) = hv_eiter;
+
+ hv_magic(hv, (GV *)NULL, 'E');
+
+ TAINT_NOT;
+
+ return hv;
+}
+
+static void
+modperl_perl_global_gvhv_save(pTHX_ modperl_perl_global_gvhv_t *gvhv)
+{
+ HV *hv = GvHV(gvhv->gv);
+#if 0
+ U32 mg_flags;
+ MAGIC *mg = SvMAGIC(hv);
+
+ /*
+ * there should only be a small number of entries in %ENV
+ * at this point: modperl_env.c:modperl_env_const_vars[],
+ * PerlPassEnv and top-level PerlSetEnv
+ * XXX: still; could have have something faster than newHVhv()
+ * especially if we add another GVHV to the globals table that
+ * might have more entries
+ */
+
+ /* makes newHVhv() faster in bleedperl */
+ MP_magical_untie(hv, mg_flags);
+
+ gvhv->tmphv = newHVhv(hv);
+ TAINT_NOT;
+
+ /* reapply magic flags */
+ MP_magical_tie(hv, mg_flags);
+ MP_magical_tie(gvhv->tmphv, mg_flags);
+
+ if (mg && mg->mg_type && !SvMAGIC(gvhv->tmphv)) {
+ /* propagate SvMAGIC(hv) to SvMAGIC(gvhv->tmphv) */
+ /* XXX: maybe newHVhv should do this? */
+ hv_magic(gvhv->tmphv, (GV *)NULL, mg->mg_type);
+ }
+#else
+ gvhv->tmphv = copyENV(aTHX_ hv);
+#endif
+
+ gvhv->orighv = hv;
+ GvHV(gvhv->gv) = gvhv->tmphv;
+}
+
+static void
+modperl_perl_global_gvhv_restore(pTHX_ modperl_perl_global_gvhv_t *gvhv)
+{
+ U32 mg_flags;
+
+ GvHV(gvhv->gv) = gvhv->orighv;
+
+ /* loose magic for hv_clear()
+ * e.g. for %ENV don't want to clear environ array
+ */
+ MP_magical_untie(gvhv->tmphv, mg_flags);
+ SvREFCNT_dec(gvhv->tmphv);
+
+ /* avoiding -Wall warning */
+ mg_flags = mg_flags;
+}
+
+static void
+modperl_perl_global_gvav_save(pTHX_ modperl_perl_global_gvav_t *gvav)
+{
+ gvav->origav = GvAV(gvav->gv);
+ gvav->tmpav = newAV();
+ modperl_perl_av_push_elts_ref(aTHX_ gvav->tmpav, gvav->origav);
+ GvAV(gvav->gv) = gvav->tmpav;
+}
+
+static void
+modperl_perl_global_gvav_restore(pTHX_ modperl_perl_global_gvav_t *gvav)
+{
+ GvAV(gvav->gv) = gvav->origav;
+ SvREFCNT_dec(gvav->tmpav);
+}
+
+static void
+modperl_perl_global_gvio_save(pTHX_ modperl_perl_global_gvio_t *gvio)
+{
+ gvio->flags = IoFLAGS(GvIOp(gvio->gv));
+}
+
+static void
+modperl_perl_global_gvio_restore(pTHX_ modperl_perl_global_gvio_t *gvio)
+{
+ IoFLAGS(GvIOp(gvio->gv)) = gvio->flags;
+}
+
+static void
+modperl_perl_global_svpv_save(pTHX_ modperl_perl_global_svpv_t *svpv)
+{
+ svpv->cur = SvCUR(*svpv->sv);
+ strncpy(svpv->pv, SvPVX(*svpv->sv), sizeof(svpv->pv));
+}
+
+static void
+modperl_perl_global_svpv_restore(pTHX_ modperl_perl_global_svpv_t *svpv)
+{
+ sv_setpvn(*svpv->sv, svpv->pv, svpv->cur);
+}
+
+typedef enum {
+ MP_GLOBAL_AVCV,
+ MP_GLOBAL_GVHV,
+ MP_GLOBAL_GVAV,
+ MP_GLOBAL_GVIO,
+ MP_GLOBAL_SVPV
+} modperl_perl_global_types_e;
+
+typedef struct {
+ char *name;
+ int offset;
+ modperl_perl_global_types_e type;
+} modperl_perl_global_entry_t;
+
+#define MP_GLOBAL_OFFSET(m) \
+ STRUCT_OFFSET(modperl_perl_globals_t, m)
+
+static modperl_perl_global_entry_t MP_perl_global_entries[] = {
+ {"END", MP_GLOBAL_OFFSET(end), MP_GLOBAL_AVCV}, /* END */
+ {"ENV", MP_GLOBAL_OFFSET(env), MP_GLOBAL_GVHV}, /* %ENV */
+ {"INC", MP_GLOBAL_OFFSET(inc), MP_GLOBAL_GVAV}, /* @INC */
+ {"STDOUT", MP_GLOBAL_OFFSET(defout), MP_GLOBAL_GVIO}, /* $| */
+ {"/", MP_GLOBAL_OFFSET(rs), MP_GLOBAL_SVPV}, /* $/ */
+ {NULL}
+};
+
+#define MP_PERL_GLOBAL_SAVE(type, ptr) \
+ modperl_perl_global_##type##_save( \
+ aTHX_ (modperl_perl_global_##type##_t *)&(*ptr))
+
+#define MP_PERL_GLOBAL_RESTORE(type, ptr) \
+ modperl_perl_global_##type##_restore( \
+ aTHX_ (modperl_perl_global_##type##_t *)&(*ptr))
+
+#define MP_dGLOBAL_PTR(globals, entries) \
+ apr_uint64_t **ptr = (apr_uint64_t **) \
+ ((char *)globals + (int)(long)entries->offset)
+
+static void modperl_perl_global_save(pTHX_ modperl_perl_globals_t *globals,
+ modperl_perl_global_entry_t *entries)
+{
+ modperl_perl_global_init(aTHX_ globals);
+
+ while (entries->name) {
+ MP_dGLOBAL_PTR(globals, entries);
+
+ switch (entries->type) {
+ case MP_GLOBAL_AVCV:
+ MP_PERL_GLOBAL_SAVE(avcv, ptr);
+ break;
+ case MP_GLOBAL_GVHV:
+ MP_PERL_GLOBAL_SAVE(gvhv, ptr);
+ break;
+ case MP_GLOBAL_GVAV:
+ MP_PERL_GLOBAL_SAVE(gvav, ptr);
+ break;
+ case MP_GLOBAL_GVIO:
+ MP_PERL_GLOBAL_SAVE(gvio, ptr);
+ break;
+ case MP_GLOBAL_SVPV:
+ MP_PERL_GLOBAL_SAVE(svpv, ptr);
+ break;
+ }
+
+ entries++;
+ }
+}
+
+static void modperl_perl_global_restore(pTHX_ modperl_perl_globals_t *globals,
+ modperl_perl_global_entry_t *entries)
+{
+ while (entries->name) {
+ MP_dGLOBAL_PTR(globals, entries);
+
+ switch (entries->type) {
+ case MP_GLOBAL_AVCV:
+ MP_PERL_GLOBAL_RESTORE(avcv, ptr);
+ break;
+ case MP_GLOBAL_GVHV:
+ MP_PERL_GLOBAL_RESTORE(gvhv, ptr);
+ break;
+ case MP_GLOBAL_GVAV:
+ MP_PERL_GLOBAL_RESTORE(gvav, ptr);
+ break;
+ case MP_GLOBAL_GVIO:
+ MP_PERL_GLOBAL_RESTORE(gvio, ptr);
+ break;
+ case MP_GLOBAL_SVPV:
+ MP_PERL_GLOBAL_RESTORE(svpv, ptr);
+ break;
+ }
+
+ entries++;
+ }
+}
+
+void modperl_perl_global_request_save(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+ modperl_perl_global_save(aTHX_ &rcfg->perl_globals,
+ MP_perl_global_entries);
+}
+
+void modperl_perl_global_request_restore(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+ modperl_perl_global_restore(aTHX_ &rcfg->perl_globals,
+ MP_perl_global_entries);
+
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl_global.h b/2_0_13/src/modules/perl/modperl_perl_global.h
new file mode 100644
index 0000000..5f1fc44
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl_global.h
@@ -0,0 +1,98 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_PERL_GLOBAL_H
+#define MODPERL_PERL_GLOBAL_H
+
+#define MP_MODGLOBAL_FETCH(gkey) \
+ hv_fetch_he(PL_modglobal, (char *)gkey->val, gkey->len, gkey->hash)
+
+#define MP_MODGLOBAL_STORE_HV(gkey) \
+ (HV*)*hv_store(PL_modglobal, gkey->val, gkey->len, \
+ (SV*)newHV(), gkey->hash)
+
+typedef struct {
+ const char *name;
+ const char *val;
+ I32 len;
+ U32 hash;
+} modperl_modglobal_key_t;
+
+typedef enum {
+ MP_MODGLOBAL_END
+} modperl_modglobal_key_e;
+
+typedef struct {
+ AV **av;
+ modperl_modglobal_key_e key;
+} modperl_perl_global_avcv_t;
+
+typedef struct {
+ GV *gv;
+ AV *tmpav;
+ AV *origav;
+} modperl_perl_global_gvav_t;
+
+typedef struct {
+ GV *gv;
+ HV *tmphv;
+ HV *orighv;
+} modperl_perl_global_gvhv_t;
+
+typedef struct {
+ GV *gv;
+ char flags;
+} modperl_perl_global_gvio_t;
+
+typedef struct {
+ SV **sv;
+ char pv[256]; /* XXX: only need enough for $/ at the moment */
+ I32 cur;
+} modperl_perl_global_svpv_t;
+
+typedef struct {
+ modperl_perl_global_avcv_t end;
+ modperl_perl_global_gvhv_t env;
+ modperl_perl_global_gvav_t inc;
+ modperl_perl_global_gvio_t defout;
+ modperl_perl_global_svpv_t rs;
+} modperl_perl_globals_t;
+
+void modperl_modglobal_hash_keys(pTHX);
+
+modperl_modglobal_key_t *modperl_modglobal_lookup(pTHX_ const char *name);
+
+void modperl_perl_global_request_save(pTHX_ request_rec *r);
+
+void modperl_perl_global_request_restore(pTHX_ request_rec *r);
+
+void modperl_perl_global_avcv_register(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen);
+
+void modperl_perl_global_avcv_call(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen);
+
+void modperl_perl_global_avcv_clear(pTHX_ modperl_modglobal_key_t *gkey,
+ const char *package, I32 packlen);
+
+#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl_includes.h b/2_0_13/src/modules/perl/modperl_perl_includes.h
new file mode 100644
index 0000000..3b85b49
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl_includes.h
@@ -0,0 +1,148 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_PERL_INCLUDES_H
+#define MODPERL_PERL_INCLUDES_H
+
+/* header files for Perl */
+
+#ifndef PERL_NO_GET_CONTEXT
+# define PERL_NO_GET_CONTEXT
+#endif
+
+#define PERLIO_NOT_STDIO 0
+
+#include "config.h"
+
+/*
+ * sizeof(struct PerlInterpreter) changes #ifdef USE_LARGE_FILES
+ * apache-2.0 cannot be compiled with lfs because of sendfile.h
+ * the PERL_CORE optimization is a no-no in this case
+ */
+#if defined(USE_ITHREADS) && !defined(USE_LARGE_FILES)
+# define PERL_CORE
+#endif
+
+#ifdef MP_SOURCE_SCAN
+/* XXX: C::Scan does not properly remove __attribute__ within
+ * function prototypes; so we just rip them all out via cpp
+ */
+# undef __attribute__
+# define __attribute__(arg)
+
+# ifdef MP_SOURCE_SCAN_NEED_ITHREADS
+/* just need to have pTHX_ defined for proper prototypes */
+# define USE_ITHREADS
+# endif
+#endif
+
+#ifdef WIN32
+# define uid_t perl_uid_t
+# define gid_t perl_gid_t
+# ifdef exit
+# undef exit
+# endif
+#endif
+
+/* needed starting from 5.8.2 to access the PERL_HASH_INTERNAL macro
+ * in hv.h. we use it in modperl_util.c */
+#define PERL_HASH_INTERNAL_ACCESS
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#if defined(WIN32) && defined(USE_LARGE_FILES)
+# ifdef malloc
+# undef malloc
+# endif
+# ifdef free
+# undef free
+# endif
+#endif
+
+#include "modperl_perl_unembed.h"
+
+/* avoiding -Wall warning */
+
+#undef dNOOP
+#define dNOOP extern int __attribute__ ((unused)) Perl___notused___modperl
+
+#ifndef G_METHOD
+# define G_METHOD 64
+#endif
+
+#ifndef PERL_MAGIC_tied
+# define PERL_MAGIC_tied 'P'
+#endif
+
+#ifndef PERL_MAGIC_tiedscalar
+# define PERL_MAGIC_tiedscalar 'q'
+#endif
+
+#ifndef PERL_MAGIC_ext
+# define PERL_MAGIC_ext '~'
+#endif
+
+#if defined(__APPLE__) && !defined(PERL_CORE) && !defined(environ)
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron())
+#endif
+
+/* sv_copypv was added in perl 5.7.3 */
+#ifndef sv_copypv
+# define sv_copypv(dsv, ssv) \
+ STMT_START { \
+ STRLEN len; \
+ char *s; \
+ s = SvPV(ssv, len); \
+ sv_setpvn(dsv, s, len); \
+ if (SvUTF8(ssv)) { \
+ SvUTF8_on(dsv); \
+ } \
+ else { \
+ SvUTF8_off(dsv); \
+ } \
+ } STMT_END
+#endif
+
+
+/* perl bug workaround: with USE_ITHREADS perl leaks pthread_key_t on
+ * every reload of libperl.{a,so} (it's allocated on the very first
+ * perl_alloc() and never freed). This becomes a problem on apache
+ * restart: if the OS limit is 1024, 1024 restarts later things will
+ * start crashing */
+/* XXX: once and if it's fixed in perl, we need to disable it for the
+ * versions that have it fixed, otherwise it'll crash because it'll be
+ * freed twice */
+#ifdef USE_ITHREADS
+#define MP_PERL_FREE_THREAD_KEY_WORKAROUND \
+ if (PL_curinterp) { \
+ FREE_THREAD_KEY; \
+ PL_curinterp = NULL; \
+ }
+#else
+#define MP_PERL_FREE_THREAD_KEY_WORKAROUND
+#endif
+
+#endif /* MODPERL_PERL_INCLUDES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl_pp.c b/2_0_13/src/modules/perl/modperl_perl_pp.c
new file mode 100644
index 0000000..881d99e
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl_pp.c
@@ -0,0 +1,122 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+static enum opcode MP_pp_map[] = {
+#ifdef MP_REFGEN_FIXUP
+ OP_SREFGEN,
+#endif
+ OP_REQUIRE
+};
+
+typedef OP * (*modperl_pp_t)(pTHX);
+
+static modperl_pp_t MP_PERL_ppaddr[MP_OP_max];
+
+#ifdef MP_REFGEN_FIXUP
+
+/*
+ * nasty workaround for bug fixed in bleedperl (11536 + 11553)
+ * XXX: when 5.8.0 is released + stable, we will require 5.8.0
+ * if ithreads are enabled.
+ */
+
+static OP *modperl_pp_srefgen(pTHX)
+{
+ dSP;
+ OP *o;
+ SV *sv = *SP;
+
+ if (SvPADTMP(sv) && IS_PADGV(sv)) {
+ /* prevent S_refto from making a copy of the GV,
+ * tricking it to SvREFCNT_inc and point to this one instead.
+ */
+ SvPADTMP_off(sv);
+ }
+ else {
+ sv = (SV *)NULL;
+ }
+
+ /* o = Perl_pp_srefgen(aTHX) */
+ o = MP_PERL_ppaddr[MP_OP_SREFGEN](aTHX);
+
+ if (sv) {
+ /* restore original flags */
+ SvPADTMP_on(sv);
+ }
+
+ return o;
+}
+
+#endif /* MP_REFGEN_FIXUP */
+
+static OP *modperl_pp_require(pTHX)
+{
+ /* nothing yet */
+ return MP_PERL_ppaddr[MP_OP_REQUIRE](aTHX);
+}
+
+static modperl_pp_t MP_ppaddr[] = {
+#ifdef MP_REFGEN_FIXUP
+ modperl_pp_srefgen,
+#endif
+ modperl_pp_require
+};
+
+void modperl_perl_pp_set(modperl_perl_opcode_e idx)
+{
+ int pl_idx = MP_pp_map[idx];
+
+ /* save original */
+ MP_PERL_ppaddr[idx] = PL_ppaddr[pl_idx];
+
+ /* replace with our own */
+ PL_ppaddr[pl_idx] = MP_ppaddr[idx];
+}
+
+void modperl_perl_pp_set_all(void)
+{
+ int i;
+
+ for (i=0; i<MP_OP_max; i++) {
+ modperl_perl_pp_set(i);
+ }
+}
+
+void modperl_perl_pp_unset(modperl_perl_opcode_e idx)
+{
+ int pl_idx = MP_pp_map[idx];
+
+ /* restore original */
+ PL_ppaddr[pl_idx] = MP_PERL_ppaddr[idx];
+}
+
+void modperl_perl_pp_unset_all(void)
+{
+ int i;
+
+ for (i=0; i<MP_OP_max; i++) {
+ modperl_perl_pp_unset(i);
+ }
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl_pp.h b/2_0_13/src/modules/perl/modperl_perl_pp.h
new file mode 100644
index 0000000..2386c3e
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl_pp.h
@@ -0,0 +1,50 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_PERL_PP_H
+#define MODPERL_PERL_PP_H
+
+#define MP_PERL_BRANCH(r, v) \
+ (PERL_REVISION == r && PERL_VERSION == v)
+
+#if defined(USE_ITHREADS) && MP_PERL_BRANCH(5, 6)
+# define MP_REFGEN_FIXUP
+#endif
+
+typedef enum {
+#ifdef MP_REFGEN_FIXUP
+ MP_OP_SREFGEN,
+#endif
+ MP_OP_REQUIRE,
+ MP_OP_max
+} modperl_perl_opcode_e;
+
+void modperl_perl_pp_set(modperl_perl_opcode_e idx);
+
+void modperl_perl_pp_set_all(void);
+
+void modperl_perl_pp_unset(modperl_perl_opcode_e idx);
+
+void modperl_perl_pp_unset_all(void);
+
+#endif /* MODPERL_PERL_PP_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_perl_unembed.h b/2_0_13/src/modules/perl/modperl_perl_unembed.h
new file mode 100644
index 0000000..4db14a5
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_perl_unembed.h
@@ -0,0 +1,52 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_PERL_UNEMBED_H
+#define MODPERL_PERL_UNEMBED_H
+
+#ifdef PERL_CORE
+# ifndef croak
+# define croak Perl_croak_nocontext
+# endif
+#endif
+
+/* avoiding namespace collisions */
+
+/* from XSUB.h */
+/* mod_perl.c calls exit() in a few places */
+#undef exit
+/* modperl_tipool.c references abort() */
+#undef abort
+/* these three clash with apr bucket structure member names */
+#undef link
+#undef read
+#undef free
+/* modperl_perl.c */
+#ifdef WIN32
+# undef getpid
+# undef getenv
+#endif
+
+#undef list
+
+#endif /* MODPERL_PERL_UNEMBED_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_svptr_table.c b/2_0_13/src/modules/perl/modperl_svptr_table.c
new file mode 100644
index 0000000..e63a3b8
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_svptr_table.c
@@ -0,0 +1,312 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/*
+ * modperl_svptr_table api is an add-on to the Perl ptr_table_ api.
+ * we use a PTR_TBL_t to map config structures (e.g. from parsed
+ * httpd.conf or .htaccess), where each interpreter needs to have its
+ * own copy of the Perl SV object. we do not use an HV* for this, because
+ * the HV keys must be SVs with a string value, too much overhead.
+ * we do not use an apr_hash_t because they only have the lifetime of
+ * the pool used to create them. which may or may not be the same lifetime
+ * of the objects we need to lookup.
+ */
+
+#ifdef USE_ITHREADS
+
+#if MP_PERL_BRANCH(5, 6)
+# define my_sv_dup(s, p) SvREFCNT_inc(sv_dup(s))
+
+typedef struct {
+ AV *stashes;
+ UV flags;
+ PerlInterpreter *proto_perl;
+} CLONE_PARAMS;
+
+#else
+# ifdef sv_dup_inc
+# define my_sv_dup(s, p) sv_dup_inc(s, p)
+# else
+# define my_sv_dup(s, p) SvREFCNT_inc(sv_dup(s, p))
+# endif
+#endif
+
+/*
+ * copy a PTR_TBL_t whos PTR_TBL_ENT_t values are SVs.
+ * the SVs are dup-ed so each interpreter has its own copy.
+ */
+PTR_TBL_t *modperl_svptr_table_clone(pTHX_ PerlInterpreter *proto_perl,
+ PTR_TBL_t *source)
+{
+ UV i;
+ PTR_TBL_t *tbl;
+ PTR_TBL_ENT_t **src_ary, **dst_ary;
+ CLONE_PARAMS parms;
+
+ Newxz(tbl, 1, PTR_TBL_t);
+ tbl->tbl_max = source->tbl_max;
+ tbl->tbl_items = source->tbl_items;
+ Newxz(tbl->tbl_ary, tbl->tbl_max + 1, PTR_TBL_ENT_t *);
+
+ dst_ary = tbl->tbl_ary;
+ src_ary = source->tbl_ary;
+
+ Zero(&parms, 1, CLONE_PARAMS);
+ parms.flags = 0;
+ parms.stashes = newAV();
+
+ for (i=0; i < source->tbl_max; i++, dst_ary++, src_ary++) {
+ PTR_TBL_ENT_t *src_ent, *dst_ent=NULL;
+
+ if (!*src_ary) {
+ continue;
+ }
+
+ for (src_ent = *src_ary;
+ src_ent;
+ src_ent = src_ent->next)
+ {
+ if (dst_ent == NULL) {
+ Newxz(dst_ent, 1, PTR_TBL_ENT_t);
+ *dst_ary = dst_ent;
+ }
+ else {
+ Newxz(dst_ent->next, 1, PTR_TBL_ENT_t);
+ dst_ent = dst_ent->next;
+ }
+
+ /* key is just a pointer we do not modify, no need to copy */
+ dst_ent->oldval = src_ent->oldval;
+
+ dst_ent->newval = my_sv_dup((SV*)src_ent->newval, &parms);
+ }
+ }
+
+ SvREFCNT_dec(parms.stashes);
+
+ return tbl;
+}
+
+#endif
+
+/*
+ * need to free the SV values in addition to ptr_table_free
+ */
+void modperl_svptr_table_destroy(pTHX_ PTR_TBL_t *tbl)
+{
+ UV i;
+ PTR_TBL_ENT_t **ary = tbl->tbl_ary;
+
+ for (i=0; i < tbl->tbl_max; i++, ary++) {
+ PTR_TBL_ENT_t *ent;
+
+ if (!*ary) {
+ continue;
+ }
+
+ for (ent = *ary; ent; ent = ent->next) {
+ if (!ent->newval) {
+ continue;
+ }
+
+ SvREFCNT_dec((SV*)ent->newval);
+ ent->newval = NULL;
+ }
+ }
+
+ modperl_svptr_table_free(aTHX_ tbl);
+}
+
+/*
+ * the Perl ptr_table_ api does not provide a function to remove
+ * an entry from the table. we need to SvREFCNT_dec the SV value
+ * anyhow.
+ */
+void modperl_svptr_table_delete(pTHX_ PTR_TBL_t *tbl, void *key)
+{
+ PTR_TBL_ENT_t *entry, **oentry;
+ UV hash = PTR2UV(key);
+
+ oentry = &tbl->tbl_ary[hash & tbl->tbl_max];
+ entry = *oentry;
+
+ for (; entry; oentry = &entry->next, entry = *oentry) {
+ if (entry->oldval == key) {
+ *oentry = entry->next;
+ SvREFCNT_dec((SV*)entry->newval);
+ Safefree(entry);
+ tbl->tbl_items--;
+ return;
+ }
+ }
+}
+
+/*
+ * XXX: the following are a copy of the Perl 5.8.0 Perl_ptr_table api
+ * renamed s/Perl_ptr/modperl_svptr/g;
+ * two reasons:
+ * these functions do not exist without -DUSE_ITHREADS
+ * the clear/free functions do not exist in 5.6.x
+ */
+
+/* create a new pointer-mapping table */
+
+PTR_TBL_t *
+modperl_svptr_table_new(pTHX)
+{
+ PTR_TBL_t *tbl;
+ Newxz(tbl, 1, PTR_TBL_t);
+ tbl->tbl_max = 511;
+ tbl->tbl_items = 0;
+ Newxz(tbl->tbl_ary, tbl->tbl_max + 1, PTR_TBL_ENT_t*);
+ return tbl;
+}
+
+/* map an existing pointer using a table */
+
+void *
+modperl_svptr_table_fetch(pTHX_ PTR_TBL_t *tbl, void *sv)
+{
+ PTR_TBL_ENT_t *tblent;
+ UV hash = PTR2UV(sv);
+ MP_ASSERT(tbl);
+ tblent = tbl->tbl_ary[hash & tbl->tbl_max];
+ for (; tblent; tblent = tblent->next) {
+ if (tblent->oldval == sv)
+ return tblent->newval;
+ }
+ return (void*)NULL;
+}
+
+/* add a new entry to a pointer-mapping table */
+
+void
+modperl_svptr_table_store(pTHX_ PTR_TBL_t *tbl, void *oldv, void *newv)
+{
+ PTR_TBL_ENT_t *tblent, **otblent;
+ /* XXX this may be pessimal on platforms where pointers aren't good
+ * hash values e.g. if they grow faster in the most significant
+ * bits */
+ UV hash = PTR2UV(oldv);
+ bool i = 1;
+
+ MP_ASSERT(tbl);
+ otblent = &tbl->tbl_ary[hash & tbl->tbl_max];
+ for (tblent = *otblent; tblent; i=0, tblent = tblent->next) {
+ if (tblent->oldval == oldv) {
+ tblent->newval = newv;
+ return;
+ }
+ }
+ Newxz(tblent, 1, PTR_TBL_ENT_t);
+ tblent->oldval = oldv;
+ tblent->newval = newv;
+ tblent->next = *otblent;
+ *otblent = tblent;
+ tbl->tbl_items++;
+ if (i && tbl->tbl_items > tbl->tbl_max)
+ modperl_svptr_table_split(aTHX_ tbl);
+}
+
+/* double the hash bucket size of an existing ptr table */
+
+void
+modperl_svptr_table_split(pTHX_ PTR_TBL_t *tbl)
+{
+ PTR_TBL_ENT_t **ary = tbl->tbl_ary;
+ UV oldsize = tbl->tbl_max + 1;
+ UV newsize = oldsize * 2;
+ UV i;
+
+ Renew(ary, newsize, PTR_TBL_ENT_t*);
+ Zero(&ary[oldsize], newsize-oldsize, PTR_TBL_ENT_t*);
+ tbl->tbl_max = --newsize;
+ tbl->tbl_ary = ary;
+ for (i=0; i < oldsize; i++, ary++) {
+ PTR_TBL_ENT_t **curentp, **entp, *ent;
+ if (!*ary)
+ continue;
+ curentp = ary + oldsize;
+ for (entp = ary, ent = *ary; ent; ent = *entp) {
+ if ((newsize & PTR2UV(ent->oldval)) != i) {
+ *entp = ent->next;
+ ent->next = *curentp;
+ *curentp = ent;
+ continue;
+ }
+ else
+ entp = &ent->next;
+ }
+ }
+}
+
+/* remove all the entries from a ptr table */
+
+void
+modperl_svptr_table_clear(pTHX_ PTR_TBL_t *tbl)
+{
+ register PTR_TBL_ENT_t **array;
+ register PTR_TBL_ENT_t *entry;
+ register PTR_TBL_ENT_t *oentry = (PTR_TBL_ENT_t *)NULL;
+ UV riter = 0;
+ UV max;
+
+ if (!tbl || !tbl->tbl_items) {
+ return;
+ }
+
+ array = tbl->tbl_ary;
+ entry = array[0];
+ max = tbl->tbl_max;
+
+ for (;;) {
+ if (entry) {
+ oentry = entry;
+ entry = entry->next;
+ Safefree(oentry);
+ }
+ if (!entry) {
+ if (++riter > max) {
+ break;
+ }
+ entry = array[riter];
+ }
+ }
+
+ tbl->tbl_items = 0;
+}
+
+/* clear and free a ptr table */
+
+void
+modperl_svptr_table_free(pTHX_ PTR_TBL_t *tbl)
+{
+ if (!tbl) {
+ return;
+ }
+ modperl_svptr_table_clear(aTHX_ tbl);
+ Safefree(tbl->tbl_ary);
+ Safefree(tbl);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_svptr_table.h b/2_0_13/src/modules/perl/modperl_svptr_table.h
new file mode 100644
index 0000000..673f643
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_svptr_table.h
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_SVPTR_TABLE_H
+#define MODPERL_SVPTR_TABLE_H
+
+#ifdef USE_ITHREADS
+
+PTR_TBL_t *modperl_svptr_table_clone(pTHX_ PerlInterpreter *proto_perl,
+ PTR_TBL_t *source);
+
+#endif
+
+void modperl_svptr_table_destroy(pTHX_ PTR_TBL_t *tbl);
+
+void modperl_svptr_table_delete(pTHX_ PTR_TBL_t *tbl, void *key);
+
+/*
+ * XXX: the following are a copy of the Perl 5.8.0 Perl_ptr_table api
+ * renamed s/Perl_ptr/modperl_svptr/g;
+ * two reasons:
+ * these functions do not exist without -DUSE_ITHREADS
+ * the clear/free functions do not exist in 5.6.x
+ */
+
+PTR_TBL_t *
+modperl_svptr_table_new(pTHX);
+
+void *
+modperl_svptr_table_fetch(pTHX_ PTR_TBL_t *tbl, void *sv);
+
+void
+modperl_svptr_table_store(pTHX_ PTR_TBL_t *tbl, void *oldv, void *newv);
+
+void
+modperl_svptr_table_split(pTHX_ PTR_TBL_t *tbl);
+
+void
+modperl_svptr_table_clear(pTHX_ PTR_TBL_t *tbl);
+
+void
+modperl_svptr_table_free(pTHX_ PTR_TBL_t *tbl);
+
+#endif /* MODPERL_SVPTR_TABLE_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_sys.c b/2_0_13/src/modules/perl/modperl_sys.c
new file mode 100644
index 0000000..3ce3cbc
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_sys.c
@@ -0,0 +1,76 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_largefiles.h"
+#include "mod_perl.h"
+
+/*
+ * Stat_t needs flags in modperl_largefiles.h
+ */
+int modperl_sys_is_dir(pTHX_ SV *sv)
+{
+ Stat_t statbuf;
+ STRLEN n_a;
+ char *name = SvPV(sv, n_a);
+
+ if (PerlLIO_stat(name, &statbuf) < 0) {
+ return 0;
+ }
+
+ return S_ISDIR(statbuf.st_mode);
+}
+
+/*
+ * Perl does not provide this abstraction.
+ * APR does, but requires a pool. efforts to expose this area of apr
+ * failed. so we roll our own. *sigh*
+ */
+int modperl_sys_dlclose(void *handle)
+{
+#if defined(MP_SYS_DL_DLOPEN)
+#ifdef I_DLFCN
+#include <dlfcn.h>
+#else
+#include <nlist.h>
+#include <link.h>
+#endif
+ return dlclose(handle) == 0;
+#elif defined(MP_SYS_DL_DYLD)
+ return NSUnLinkModule(handle, FALSE);
+#elif defined(MP_SYS_DL_HPUX)
+#include <dl.h>
+ shl_unload((shl_t)handle);
+ return 1;
+#elif defined(MP_SYS_DL_WIN32)
+ return FreeLibrary(handle);
+#elif defined(MP_SYS_DL_BEOS)
+ return unload_add_on(handle) < B_NO_ERROR;
+#elif defined(MP_SYS_DL_DLLLOAD)
+ return dllfree(handle) == 0;
+#elif defined(MP_SYS_DL_AIX)
+ return dlclose(handle) == 0;
+#else
+#error "modperl_sys_dlclose not defined on this platform"
+ return 0;
+#endif
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_sys.h b/2_0_13/src/modules/perl/modperl_sys.h
new file mode 100644
index 0000000..a52763a
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_sys.h
@@ -0,0 +1,37 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_SYS_H
+#define MODPERL_SYS_H
+
+/*
+ * system specific type stuff.
+ * hopefully won't be much here since Perl/APR/Apache
+ * take care of most portablity issues.
+ */
+
+int modperl_sys_is_dir(pTHX_ SV *sv);
+
+int modperl_sys_dlclose(void *handle);
+
+#endif /* MODPERL_SYS_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_time.h b/2_0_13/src/modules/perl/modperl_time.h
new file mode 100644
index 0000000..bc7cbf8
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_time.h
@@ -0,0 +1,59 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_TIME_H
+#define MODPERL_TIME_H
+
+#ifdef HZ
+# define MP_HZ HZ
+#else
+# define MP_HZ 100
+#endif
+
+#ifdef MP_TRACE
+#define dMP_TIMES \
+ struct tms start_time; \
+ struct tms end_time
+#else
+#define dMP_TIMES dNOOP
+#endif
+
+#define MP_START_TIMES() \
+ MP_TRACE_t_do((void)PerlProc_times(&start_time))
+
+#define MP_END_TIMES() \
+ MP_TRACE_t_do((void)PerlProc_times(&end_time))
+
+#define MP_PRINT_TIMES(label) \
+ MP_TRACE_t_do({ \
+ double utime = \
+ (double)(end_time.tms_utime - start_time.tms_utime)/MP_HZ; \
+ double stime = \
+ (double)(end_time.tms_stime - start_time.tms_stime)/MP_HZ; \
+ if (utime || stime) { \
+ MP_TRACE_t(MP_FUNC, "%s %5.2f user %5.2f sys", \
+ label, utime, stime); \
+ } \
+ })
+
+#endif /* MODPERL_TIME_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_tipool.c b/2_0_13/src/modules/perl/modperl_tipool.c
new file mode 100644
index 0000000..9cb0ad0
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_tipool.c
@@ -0,0 +1,410 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+#ifdef USE_ITHREADS
+
+/*
+ * tipool == "thread item pool"
+ * this module is intended to provide generic stuctures/functions
+ * for managing a "pool" of a given items (data structures) within a threaded
+ * process. at the moment, mod_perl uses this module to manage a pool
+ * of PerlInterpreter objects. it should be quite easy to reuse for
+ * other data, such as database connection handles and the like.
+ * while it is "generic" it is also tuned for Apache, making use of
+ * apr_pool_t and the like, and implementing start/max/{min,max}_spare/
+ * max_requests configuration.
+ * this is another "proof-of-concept", plenty of room for improvement here
+ */
+
+modperl_list_t *modperl_list_new()
+{
+ modperl_list_t *listp =
+ (modperl_list_t *)malloc(sizeof(*listp));
+ memset(listp, '\0', sizeof(*listp));
+ return listp;
+}
+
+modperl_list_t *modperl_list_last(modperl_list_t *list)
+{
+ while (list->next) {
+ list = list->next;
+ }
+
+ return list;
+}
+
+modperl_list_t *modperl_list_first(modperl_list_t *list)
+{
+ while (list->prev) {
+ list = list->prev;
+ }
+
+ return list;
+}
+
+modperl_list_t *modperl_list_append(modperl_list_t *list,
+ modperl_list_t *new_list)
+{
+ modperl_list_t *last;
+
+ new_list->prev = new_list->next = NULL;
+
+ if (!list) {
+ return new_list;
+ }
+
+ last = modperl_list_last(list);
+
+ last->next = new_list;
+ new_list->prev = last;
+
+ return list;
+}
+
+modperl_list_t *modperl_list_prepend(modperl_list_t *list,
+ modperl_list_t *new_list)
+{
+ new_list->prev = new_list->next = NULL;
+
+ if (!list) {
+ return new_list;
+ }
+
+ if (list->prev) {
+ list->prev->next = new_list;
+ new_list->prev = list->prev;
+ }
+
+ list->prev = new_list;
+ new_list->next = list;
+
+ return new_list;
+}
+
+modperl_list_t *modperl_list_remove(modperl_list_t *list,
+ modperl_list_t *rlist)
+{
+ modperl_list_t *tmp = list;
+
+ while (tmp) {
+ if (tmp != rlist) {
+ tmp = tmp->next;
+ }
+ else {
+ if (tmp->prev) {
+ tmp->prev->next = tmp->next;
+ }
+ if (tmp->next) {
+ tmp->next->prev = tmp->prev;
+ }
+ if (list == tmp) {
+ list = list->next;
+ }
+
+ break;
+ }
+ }
+
+#ifdef MP_TRACE
+ if (!tmp) {
+ /* should never happen */
+ MP_TRACE_i(MP_FUNC, "failed to find 0x%lx in list 0x%lx",
+ (unsigned long)rlist, (unsigned long)list);
+ }
+#endif
+
+ return list;
+}
+
+modperl_list_t *modperl_list_remove_data(modperl_list_t *list,
+ void *data,
+ modperl_list_t **listp)
+{
+ modperl_list_t *tmp = list;
+
+ while (tmp) {
+ if (tmp->data != data) {
+ tmp = tmp->next;
+ }
+ else {
+ *listp = tmp;
+ if (tmp->prev) {
+ tmp->prev->next = tmp->next;
+ }
+ if (tmp->next) {
+ tmp->next->prev = tmp->prev;
+ }
+ if (list == tmp) {
+ list = list->next;
+ }
+
+ break;
+ }
+ }
+
+ return list;
+}
+
+modperl_tipool_t *modperl_tipool_new(apr_pool_t *p,
+ modperl_tipool_config_t *cfg,
+ modperl_tipool_vtbl_t *func,
+ void *data)
+{
+ modperl_tipool_t *tipool =
+ (modperl_tipool_t *)apr_pcalloc(p, sizeof(*tipool));
+
+ tipool->cfg = cfg;
+ tipool->func = func;
+ tipool->data = data;
+
+ MUTEX_INIT(&tipool->tiplock);
+ COND_INIT(&tipool->available);
+
+ return tipool;
+}
+
+void modperl_tipool_init(modperl_tipool_t *tipool)
+{
+ int i;
+
+ for (i=0; i<tipool->cfg->start; i++) {
+ void *item =
+ (*tipool->func->tipool_sgrow)(tipool, tipool->data);
+
+ modperl_tipool_add(tipool, item);
+ }
+
+ MP_TRACE_i(MP_FUNC, "start=%d, max=%d, min_spare=%d, max_spare=%d",
+ tipool->cfg->start, tipool->cfg->max,
+ tipool->cfg->min_spare, tipool->cfg->max_spare);
+
+}
+
+void modperl_tipool_destroy(modperl_tipool_t *tipool)
+{
+ while (tipool->idle) {
+ modperl_list_t *listp;
+
+ if (tipool->func->tipool_destroy) {
+ (*tipool->func->tipool_destroy)(tipool, tipool->data,
+ tipool->idle->data);
+ }
+ tipool->size--;
+ listp = tipool->idle->next;
+ free(tipool->idle);
+ tipool->idle = listp;
+ }
+
+ if (tipool->busy) {
+ MP_TRACE_i(MP_FUNC, "ERROR: %d items still in use",
+ tipool->in_use);
+ }
+
+ MUTEX_DESTROY(&tipool->tiplock);
+ COND_DESTROY(&tipool->available);
+}
+
+void modperl_tipool_add(modperl_tipool_t *tipool, void *data)
+{
+ modperl_list_t *listp = modperl_list_new();
+
+ listp->data = data;
+
+ /* assuming tipool->tiplock has already been acquired */
+
+ tipool->idle = modperl_list_append(tipool->idle, listp);
+
+ tipool->size++;
+
+ MP_TRACE_i(MP_FUNC, "added 0x%lx (size=%d)",
+ (unsigned long)listp, tipool->size);
+}
+
+void modperl_tipool_remove(modperl_tipool_t *tipool, modperl_list_t *listp)
+{
+ /* assuming tipool->tiplock has already been acquired */
+
+ tipool->idle = modperl_list_remove(tipool->idle, listp);
+
+ tipool->size--;
+ MP_TRACE_i(MP_FUNC, "removed 0x%lx (size=%d)",
+ (unsigned long)listp, tipool->size);
+}
+
+modperl_list_t *modperl_tipool_pop(modperl_tipool_t *tipool)
+{
+ modperl_list_t *head;
+
+ modperl_tipool_lock(tipool);
+
+ if (tipool->size == tipool->in_use) {
+ if (tipool->size < tipool->cfg->max) {
+ MP_TRACE_i(MP_FUNC,
+ "no idle items, size %d < %d max",
+ tipool->size, tipool->cfg->max);
+ if (tipool->func->tipool_rgrow) {
+ void * item =
+ (*tipool->func->tipool_rgrow)(tipool, tipool->data);
+
+ modperl_tipool_add(tipool, item);
+ }
+ }
+ /* block until an item becomes available */
+ modperl_tipool_wait(tipool);
+ }
+
+ head = tipool->idle;
+
+ tipool->idle = modperl_list_remove(tipool->idle, head);
+ tipool->busy = modperl_list_append(tipool->busy, head);
+
+ tipool->in_use++;
+
+ /* XXX: this should never happen */
+ if (!head) {
+ MP_TRACE_i(MP_FUNC, "PANIC: no items available, %d of %d in use",
+ tipool->in_use, tipool->size);
+ abort();
+ }
+
+ modperl_tipool_unlock(tipool);
+
+ return head;
+}
+
+static void modperl_tipool_putback_base(modperl_tipool_t *tipool,
+ modperl_list_t *listp,
+ void *data,
+ int num_requests)
+{
+ int max_spare, max_requests;
+
+ modperl_tipool_lock(tipool);
+
+ /* remove from busy list, add back to idle */
+ /* XXX: option to sort list, e.g. on num_requests */
+
+ if (listp) {
+ tipool->busy = modperl_list_remove(tipool->busy, listp);
+ }
+ else {
+ tipool->busy = modperl_list_remove_data(tipool->busy, data, &listp);
+ }
+
+ if (!listp) {
+ /* XXX: Attempt to putback something that was never there */
+ modperl_tipool_unlock(tipool);
+ return;
+ }
+
+ tipool->idle = modperl_list_prepend(tipool->idle, listp);
+
+ tipool->in_use--;
+
+#ifdef MP_TRACE
+ if (!tipool->busy && tipool->func->tipool_dump) {
+ MP_TRACE_i(MP_FUNC, "all items idle:");
+ MP_TRACE_i_do((*tipool->func->tipool_dump)(tipool,
+ tipool->data,
+ tipool->idle));
+ }
+#endif
+
+ MP_TRACE_i(MP_FUNC, "0x%lx now available (%d in use, %d running)",
+ (unsigned long)listp->data, tipool->in_use, tipool->size);
+
+ modperl_tipool_broadcast(tipool);
+ if (tipool->in_use == (tipool->cfg->max - 1)) {
+ /* hurry up, another thread may be blocking */
+ modperl_tipool_unlock(tipool);
+ return;
+ }
+
+ max_spare = ((tipool->size - tipool->in_use) > tipool->cfg->max_spare);
+ max_requests = ((num_requests > 0) &&
+ (num_requests > tipool->cfg->max_requests));
+
+ if (max_spare) {
+ MP_TRACE_i(MP_FUNC,
+ "shrinking pool: max_spare=%d, only %d of %d in use",
+ tipool->cfg->max_spare, tipool->in_use, tipool->size);
+ }
+ else if (max_requests) {
+ MP_TRACE_i(MP_FUNC, "shrinking pool: max requests %d reached",
+ tipool->cfg->max_requests);
+ }
+
+ /* XXX: this management should probably be happening elsewhere
+ * like in a thread spawned at startup
+ */
+ if (max_spare || max_requests) {
+ modperl_tipool_remove(tipool, listp);
+
+ if (tipool->func->tipool_destroy) {
+ (*tipool->func->tipool_destroy)(tipool, tipool->data,
+ listp->data);
+ }
+
+ free(listp); /* gone for good */
+
+ if (max_requests && ((tipool->size - tipool->in_use) <
+ tipool->cfg->min_spare)) {
+ if (tipool->func->tipool_rgrow) {
+ void *item =
+ (*tipool->func->tipool_rgrow)(tipool,
+ tipool->data);
+
+ MP_TRACE_i(MP_FUNC,
+ "growing pool: min_spare=%d, %d of %d in use",
+ tipool->cfg->min_spare, tipool->in_use,
+ tipool->size);
+
+ modperl_tipool_add(tipool, item);
+ }
+ }
+ }
+
+ modperl_tipool_unlock(tipool);
+}
+
+/* _data functions are so structures (e.g. modperl_interp_t) don't
+ * need to maintain a pointer back to the modperl_list_t
+ */
+
+void modperl_tipool_putback_data(modperl_tipool_t *tipool,
+ void *data,
+ int num_requests)
+{
+ modperl_tipool_putback_base(tipool, NULL, data, num_requests);
+}
+
+void modperl_tipool_putback(modperl_tipool_t *tipool,
+ modperl_list_t *listp,
+ int num_requests)
+{
+ modperl_tipool_putback_base(tipool, listp, NULL, num_requests);
+}
+
+#endif /* USE_ITHREADS */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_tipool.h b/2_0_13/src/modules/perl/modperl_tipool.h
new file mode 100644
index 0000000..c2d15b8
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_tipool.h
@@ -0,0 +1,96 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_TIPOOL_H
+#define MODPERL_TIPOOL_H
+
+#ifdef USE_ITHREADS
+
+modperl_list_t *modperl_list_new(void);
+
+modperl_list_t *modperl_list_last(modperl_list_t *list);
+
+modperl_list_t *modperl_list_first(modperl_list_t *list);
+
+modperl_list_t *modperl_list_append(modperl_list_t *list,
+ modperl_list_t *new_list);
+
+modperl_list_t *modperl_list_prepend(modperl_list_t *list,
+ modperl_list_t *new_list);
+
+modperl_list_t *modperl_list_remove(modperl_list_t *list,
+ modperl_list_t *rlist);
+
+modperl_tipool_t *modperl_tipool_new(apr_pool_t *p,
+ modperl_tipool_config_t *cfg,
+ modperl_tipool_vtbl_t *func,
+ void *data);
+
+void modperl_tipool_init(modperl_tipool_t *tipool);
+
+void modperl_tipool_destroy(modperl_tipool_t *tipool);
+
+void modperl_tipool_add(modperl_tipool_t *tipool, void *data);
+
+void modperl_tipool_remove(modperl_tipool_t *tipool, modperl_list_t *listp);
+
+modperl_list_t *modperl_list_remove_data(modperl_list_t *list,
+ void *data,
+ modperl_list_t **listp);
+
+modperl_list_t *modperl_tipool_pop(modperl_tipool_t *tipool);
+
+void modperl_tipool_putback(modperl_tipool_t *tipool,
+ modperl_list_t *listp,
+ int num_requests);
+
+void modperl_tipool_putback_data(modperl_tipool_t *tipool, void *data,
+ int num_requests);
+
+#define modperl_tipool_wait(tipool) \
+ while (tipool->size == tipool->in_use) { \
+ MP_TRACE_i(MP_FUNC, \
+ "waiting for available tipool item in thread 0x%lx", \
+ MP_TIDF); \
+ MP_TRACE_i(MP_FUNC, "(%d items in use, %d alive)", \
+ tipool->in_use, tipool->size); \
+ COND_WAIT(&tipool->available, &tipool->tiplock); \
+ }
+
+#define modperl_tipool_broadcast(tipool) \
+ MP_TRACE_i(MP_FUNC, "broadcast available tipool item"); \
+ COND_SIGNAL(&tipool->available)
+
+#define modperl_tipool_lock(tipool) \
+ MP_TRACE_i(MP_FUNC, "about to lock tipool in thread 0x%lx", MP_TIDF); \
+ MUTEX_LOCK(&tipool->tiplock); \
+ MP_TRACE_i(MP_FUNC, "acquired tipool lock")
+
+#define modperl_tipool_unlock(tipool) \
+ MP_TRACE_i(MP_FUNC, "about to unlock tipool in thread 0x%lx", MP_TIDF); \
+ MUTEX_UNLOCK(&tipool->tiplock); \
+ MP_TRACE_i(MP_FUNC, "released tipool lock")
+
+#endif /* USE_ITHREADS */
+
+#endif /* MODPERL_TIPOOL_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_types.h b/2_0_13/src/modules/perl/modperl_types.h
new file mode 100644
index 0000000..8438f35
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_types.h
@@ -0,0 +1,289 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_TYPES_H
+#define MODPERL_TYPES_H
+
+#ifndef MP_IOBUFSIZE
+# ifdef AP_IOBUFSIZE
+# define MP_IOBUFSIZE AP_IOBUFSIZE
+# else
+# define MP_IOBUFSIZE 8192
+# endif
+#endif
+
+/* aliases */
+
+typedef request_rec subrequest_rec;
+typedef apr_array_header_t MpAV;
+typedef apr_table_t MpHV;
+typedef char char_len; /* see xs/typemap */
+
+/* mod_perl structures */
+
+typedef struct {
+ request_rec *r;
+ conn_rec *c;
+ server_rec *s;
+} modperl_rcs_t;
+
+typedef struct modperl_config_con_t modperl_config_con_t;
+
+#ifdef USE_ITHREADS
+
+typedef struct modperl_list_t modperl_list_t;
+
+struct modperl_list_t {
+ modperl_list_t *prev, *next;
+ void *data;
+};
+
+typedef struct modperl_interp_t modperl_interp_t;
+typedef struct modperl_interp_pool_t modperl_interp_pool_t;
+typedef struct modperl_tipool_t modperl_tipool_t;
+typedef struct modperl_tipool_config_t modperl_tipool_config_t;
+
+struct modperl_interp_t {
+ modperl_interp_pool_t *mip;
+ PerlInterpreter *perl;
+ int num_requests;
+ U8 flags;
+ modperl_config_con_t *ccfg;
+ int refcnt;
+#ifdef MP_TRACE
+ unsigned long tid;
+#endif
+};
+
+typedef struct {
+ /* s == startup grow
+ * r == runtime grow
+ */
+ void * (*tipool_sgrow)(modperl_tipool_t *tipool, void *data);
+ void * (*tipool_rgrow)(modperl_tipool_t *tipool, void *data);
+ void (*tipool_shrink)(modperl_tipool_t *tipool, void *data,
+ void *item);
+ void (*tipool_destroy)(modperl_tipool_t *tipool, void *data,
+ void *item);
+ void (*tipool_dump)(modperl_tipool_t *tipool, void *data,
+ modperl_list_t *listp);
+} modperl_tipool_vtbl_t;
+
+struct modperl_tipool_config_t {
+ int start; /* number of items to create at startup */
+ int min_spare; /* minimum number of spare items */
+ int max_spare; /* maximum number of spare items */
+ int max; /* maximum number of items */
+ int max_requests; /* maximum number of requests per item */
+};
+
+struct modperl_tipool_t {
+ perl_mutex tiplock;
+ perl_cond available;
+ modperl_list_t *idle, *busy;
+ int in_use; /* number of items currrently in use */
+ int size; /* current number of items */
+ void *data; /* user data */
+ modperl_tipool_config_t *cfg;
+ modperl_tipool_vtbl_t *func;
+};
+
+struct modperl_interp_pool_t {
+ server_rec *server;
+ modperl_tipool_t *tipool;
+ modperl_interp_t *parent; /* from which to perl_clone() */
+};
+
+#endif /* USE_ITHREADS */
+
+typedef U32 modperl_opts_t;
+
+typedef struct {
+ modperl_opts_t opts;
+ modperl_opts_t opts_add;
+ modperl_opts_t opts_remove;
+ modperl_opts_t opts_override;
+ modperl_opts_t opts_seen;
+ int unset;
+} modperl_options_t;
+
+typedef struct {
+ MpHV *setvars;
+ MpHV *configvars;
+ MpHV *SetEnv;
+ MpHV *PassEnv;
+ MpAV *PerlRequire, *PerlModule, *PerlPostConfigRequire;
+ MpAV *handlers_per_srv[MP_HANDLER_NUM_PER_SRV];
+ MpAV *handlers_files[MP_HANDLER_NUM_FILES];
+ MpAV *handlers_process[MP_HANDLER_NUM_PROCESS];
+ MpAV *handlers_pre_connection[MP_HANDLER_NUM_PRE_CONNECTION];
+ MpAV *handlers_connection[MP_HANDLER_NUM_CONNECTION];
+#ifdef USE_ITHREADS
+ modperl_interp_pool_t *mip;
+ modperl_tipool_config_t *interp_pool_cfg;
+#else
+ PerlInterpreter *perl;
+#endif
+#ifdef MP_USE_GTOP
+ modperl_gtop_t *gtop;
+#endif
+ MpAV *argv;
+ modperl_options_t *flags;
+ apr_hash_t *modules;
+ server_rec *server;
+} modperl_config_srv_t;
+
+typedef struct {
+ char *location;
+ char *PerlDispatchHandler;
+ MpAV *handlers_per_dir[MP_HANDLER_NUM_PER_DIR];
+ MpHV *SetEnv;
+ MpHV *setvars;
+ MpHV *configvars;
+ modperl_options_t *flags;
+} modperl_config_dir_t;
+
+typedef struct {
+ const char *file;
+ modperl_config_dir_t *dcfg;
+} modperl_require_file_t;
+
+typedef struct modperl_mgv_t modperl_mgv_t;
+
+struct modperl_mgv_t {
+ char *name;
+ int len;
+ UV hash;
+ modperl_mgv_t *next;
+};
+
+typedef struct modperl_handler_t modperl_handler_t;
+
+struct modperl_handler_t {
+ /* could be:
+ * - the lightweight gv for named subs
+ * - the lookup data in $PL_modperl{ANONSUB}
+ */
+ modperl_mgv_t *mgv_obj;
+ modperl_mgv_t *mgv_cv;
+ /* could be:
+ * - a subroutine name for named subs
+ * - NULL for anon subs
+ */
+ const char *name;
+ CV *cv;
+ U8 flags;
+ U16 attrs;
+ modperl_handler_t *next;
+};
+
+#define MP_HANDLER_TYPE_CHAR 1
+#define MP_HANDLER_TYPE_SV 2
+
+typedef struct {
+ int outcnt;
+ char outbuf[MP_IOBUFSIZE];
+ apr_pool_t *pool;
+ ap_filter_t **filters;
+ int header_parse;
+ request_rec *r;
+} modperl_wbucket_t;
+
+typedef enum {
+ MP_INPUT_FILTER_MODE,
+ MP_OUTPUT_FILTER_MODE
+} modperl_filter_mode_e;
+
+typedef struct {
+ int seen_eos;
+ int eos;
+ int flush;
+ ap_filter_t *f;
+ char *leftover;
+ apr_ssize_t remaining;
+ modperl_wbucket_t *wbucket;
+ apr_bucket *bucket;
+ apr_bucket_brigade *bb_in;
+ apr_bucket_brigade *bb_out;
+ ap_input_mode_t input_mode;
+ apr_read_type_e block;
+ apr_off_t readbytes;
+ apr_status_t rc;
+ modperl_filter_mode_e mode;
+ apr_pool_t *pool;
+ apr_pool_t *temp_pool;
+} modperl_filter_t;
+
+typedef struct {
+ int sent_eos;
+ SV *data;
+ modperl_handler_t *handler;
+#ifdef USE_ITHREADS
+ modperl_interp_t *interp;
+#endif
+} modperl_filter_ctx_t;
+
+typedef struct {
+ HV *pnotes;
+ apr_pool_t *pool;
+#ifdef USE_ITHREADS
+ modperl_interp_t *interp;
+#endif
+} modperl_pnotes_t;
+
+typedef struct {
+ modperl_pnotes_t pnotes;
+ SV *global_request_obj;
+ U8 flags;
+ int status;
+ modperl_wbucket_t *wbucket;
+ MpAV *handlers_per_dir[MP_HANDLER_NUM_PER_DIR];
+ MpAV *handlers_per_srv[MP_HANDLER_NUM_PER_SRV];
+ modperl_perl_globals_t perl_globals;
+} modperl_config_req_t;
+
+struct modperl_config_con_t {
+ modperl_pnotes_t pnotes;
+#ifdef USE_ITHREADS
+ modperl_interp_t *interp;
+#endif
+};
+
+typedef struct {
+ apr_pool_t *pool;
+ void *data;
+} modperl_cleanup_data_t;
+
+typedef struct {
+ module *modp;
+ const char *cmd_data;
+ const char *func_name;
+} modperl_module_cmd_data_t;
+
+typedef enum {
+ MP_HOOK_RUN_ALL,
+ MP_HOOK_RUN_FIRST,
+ MP_HOOK_VOID
+} modperl_hook_run_mode_e;
+
+#endif /* MODPERL_TYPES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_util.c b/2_0_13/src/modules/perl/modperl_util.c
new file mode 100644
index 0000000..dc06cde
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_util.c
@@ -0,0 +1,1268 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+int modperl_require_module(pTHX_ const char *pv, int logfailure)
+{
+ SV *sv;
+
+ dSP;
+ PUSHSTACKi(PERLSI_REQUIRE);
+ ENTER;SAVETMPS;
+ PUTBACK;
+ sv = sv_newmortal();
+ sv_setpv(sv, "require ");
+ sv_catpv(sv, pv);
+ eval_sv(sv, G_DISCARD);
+ SPAGAIN;
+ POPSTACK;
+ FREETMPS;LEAVE;
+
+ if (SvTRUE(ERRSV)) {
+ if (logfailure) {
+ (void)modperl_errsv(aTHX_ HTTP_INTERNAL_SERVER_ERROR,
+ NULL, NULL);
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int modperl_require_file(pTHX_ const char *pv, int logfailure)
+{
+ require_pv(pv);
+
+ if (SvTRUE(ERRSV)) {
+ if (logfailure) {
+ (void)modperl_errsv(aTHX_ HTTP_INTERNAL_SERVER_ERROR,
+ NULL, NULL);
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static SV *modperl_hv_request_find(pTHX_ SV *in, char *classname, CV *cv)
+{
+ static char *r_keys[] = { "r", "_r", NULL };
+ HV *hv = (HV *)SvRV(in);
+ SV *sv = (SV *)NULL;
+ int i;
+
+ for (i=0; r_keys[i]; i++) {
+ int klen = i + 1; /* assumes r_keys[] will never change */
+ SV **svp;
+
+ if ((svp = hv_fetch(hv, r_keys[i], klen, FALSE)) && (sv = *svp)) {
+ if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVHV)) {
+ /* dig deeper */
+ return modperl_hv_request_find(aTHX_ sv, classname, cv);
+ }
+ break;
+ }
+ }
+
+ if (!sv) {
+ Perl_croak(aTHX_
+ "method `%s' invoked by a `%s' object with no `r' key!",
+ cv ? GvNAME(CvGV(cv)) : "unknown",
+ (SvRV(in) && SvSTASH(SvRV(in)))
+ ? HvNAME(SvSTASH(SvRV(in)))
+ : "unknown");
+ }
+
+ return SvROK(sv) ? SvRV(sv) : sv;
+}
+
+
+/* notice that if sv is not an Apache2::ServerRec object and
+ * Apache2->request is not available, the returned global object might
+ * be not thread-safe under threaded mpms, so use with care
+ */
+
+MP_INLINE server_rec *modperl_sv2server_rec(pTHX_ SV *sv)
+{
+ if (SvOBJECT(sv) || (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG))) {
+ return INT2PTR(server_rec *, SvObjIV(sv));
+ }
+
+ /* next see if we have Apache2->request available */
+ {
+ request_rec *r = NULL;
+ (void)modperl_tls_get_request_rec(&r);
+ if (r) {
+ return r->server;
+ }
+ }
+
+ /* modperl_global_get_server_rec is not thread safe w/o locking */
+ return modperl_global_get_server_rec();
+}
+
+MP_INLINE request_rec *modperl_sv2request_rec(pTHX_ SV *sv)
+{
+ return modperl_xs_sv2request_rec(aTHX_ sv, NULL, (CV *)NULL);
+}
+
+request_rec *modperl_xs_sv2request_rec(pTHX_ SV *in, char *classname, CV *cv)
+{
+ SV *sv = (SV *)NULL;
+ MAGIC *mg;
+
+ if (SvROK(in)) {
+ SV *rv = (SV*)SvRV(in);
+
+ switch (SvTYPE(rv)) {
+ case SVt_PVMG:
+ sv = rv;
+ break;
+ case SVt_PVHV:
+ sv = modperl_hv_request_find(aTHX_ in, classname, cv);
+ break;
+ default:
+ Perl_croak(aTHX_ "panic: unsupported request_rec type %d",
+ (int)SvTYPE(rv));
+ }
+ }
+
+ /* might be Apache2::ServerRec::warn method */
+ if (!sv && !(classname && SvPOK(in) && !strEQ(classname, SvPVX(in)))) {
+ request_rec *r = NULL;
+ (void)modperl_tls_get_request_rec(&r);
+
+ if (!r) {
+ Perl_croak(aTHX_
+ "Apache2->%s called without setting Apache2->request!",
+ cv ? GvNAME(CvGV(cv)) : "unknown");
+ }
+
+ return r;
+ }
+
+ /* there could be pool magic attached to custom $r object, so make
+ * sure that mg->mg_ptr is set */
+ if ((mg = mg_find(sv, PERL_MAGIC_ext)) && mg->mg_ptr) {
+ return (request_rec *)mg->mg_ptr;
+ }
+ else {
+ if (classname && !sv_derived_from(in, classname)) {
+ /* XXX: find something faster than sv_derived_from */
+ return NULL;
+ }
+ return INT2PTR(request_rec *, SvIV(sv));
+ }
+
+ return NULL;
+}
+
+MP_INLINE SV *modperl_newSVsv_obj(pTHX_ SV *stashsv, SV *obj)
+{
+ SV *newobj;
+
+ if (!obj) {
+ obj = stashsv;
+ stashsv = (SV *)NULL;
+ }
+
+ newobj = newSVsv(obj);
+
+ if (stashsv) {
+ HV *stash = gv_stashsv(stashsv, TRUE);
+ return sv_bless(newobj, stash);
+ }
+
+ return newobj;
+}
+
+MP_INLINE SV *modperl_ptr2obj(pTHX_ char *classname, void *ptr)
+{
+ SV *sv = newSV(0);
+
+ MP_TRACE_h(MP_FUNC, "sv_setref_pv(%s, 0x%lx)",
+ classname, (unsigned long)ptr);
+ sv_setref_pv(sv, classname, ptr);
+
+ return sv;
+}
+
+int modperl_errsv(pTHX_ int status, request_rec *r, server_rec *s)
+{
+ SV *sv = ERRSV;
+ STRLEN n_a;
+
+ if (SvTRUE(sv)) {
+ if (sv_derived_from(sv, "APR::Error") &&
+ SvIVx(sv) == MODPERL_RC_EXIT) {
+ /* ModPerl::Util::exit was called */
+ return OK;
+ }
+#if 0
+ if (modperl_sv_is_http_code(ERRSV, &status)) {
+ return status;
+ }
+#endif
+ if (r) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", SvPV(sv, n_a));
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "%s", SvPV(sv, n_a));
+ }
+
+ return status;
+ }
+
+ return status;
+}
+
+/* prepends the passed sprintf-like arguments to ERRSV, which also
+ * gets stringified on the way */
+void modperl_errsv_prepend(pTHX_ const char *pat, ...)
+{
+ SV *sv;
+ va_list args;
+
+ va_start(args, pat);
+ sv = vnewSVpvf(pat, &args);
+ va_end(args);
+
+ sv_catsv(sv, ERRSV);
+ sv_copypv(ERRSV, sv);
+ sv_free(sv);
+}
+
+#define dl_librefs "DynaLoader::dl_librefs"
+#define dl_modules "DynaLoader::dl_modules"
+
+void modperl_xs_dl_handles_clear(pTHX)
+{
+ AV *librefs = get_av(dl_librefs, FALSE);
+ if (librefs) {
+ av_clear(librefs);
+ }
+}
+
+void **modperl_xs_dl_handles_get(pTHX)
+{
+ I32 i;
+ AV *librefs = get_av(dl_librefs, FALSE);
+ AV *modules = get_av(dl_modules, FALSE);
+ void **handles;
+
+ if (!librefs) {
+ MP_TRACE_r(MP_FUNC,
+ "Could not get @%s for unloading.",
+ dl_librefs);
+ return NULL;
+ }
+
+ if (!(AvFILL(librefs) >= 0)) {
+ /* dl_librefs and dl_modules are empty */
+ return NULL;
+ }
+
+ handles = (void **)malloc(sizeof(void *) * (AvFILL(librefs)+2));
+
+ for (i=0; i<=AvFILL(librefs); i++) {
+ void *handle;
+ SV *handle_sv = *av_fetch(librefs, i, FALSE);
+ SV *module_sv = *av_fetch(modules, i, FALSE);
+
+ if(!handle_sv) {
+ MP_TRACE_r(MP_FUNC,
+ "Could not fetch $%s[%d]!",
+ dl_librefs, (int)i);
+ continue;
+ }
+ handle = INT2PTR(void *, SvIV(handle_sv));
+
+ MP_TRACE_r(MP_FUNC, "%s dl handle == 0x%lx",
+ SvPVX(module_sv), (unsigned long)handle);
+ if (handle) {
+ handles[i] = handle;
+ }
+ }
+
+ av_clear(modules);
+ av_clear(librefs);
+
+ handles[i] = (void *)0;
+
+ return handles;
+}
+
+void modperl_xs_dl_handles_close(void **handles)
+{
+ int i;
+
+ if (!handles) {
+ return;
+ }
+
+ for (i=0; handles[i]; i++) {
+ MP_TRACE_r(MP_FUNC, "close 0x%lx", (unsigned long)handles[i]);
+ modperl_sys_dlclose(handles[i]);
+ }
+
+ free(handles);
+}
+
+/* XXX: There is no XS accessible splice() */
+static void modperl_av_remove_entry(pTHX_ AV *av, I32 index)
+{
+ I32 i;
+ AV *tmpav = newAV();
+
+ /* stash the entries _before_ the item to delete */
+ for (i=0; i<=index; i++) {
+ av_store(tmpav, i, SvREFCNT_inc(av_shift(av)));
+ }
+
+ /* make size at the beginning of the array */
+ av_unshift(av, index-1);
+
+ /* add stashed entries back */
+ for (i=0; i<index; i++) {
+ av_store(av, i, *av_fetch(tmpav, i, 0));
+ }
+
+ sv_free((SV *)tmpav);
+}
+
+static void modperl_package_unload_dynamic(pTHX_ const char *package,
+ I32 dl_index)
+{
+ AV *librefs = get_av(dl_librefs, 0);
+ SV *libref = *av_fetch(librefs, dl_index, 0);
+
+ modperl_sys_dlclose(INT2PTR(void *, SvIV(libref)));
+
+ /* remove package from @dl_librefs and @dl_modules */
+ modperl_av_remove_entry(aTHX_ get_av(dl_librefs, 0), dl_index);
+ modperl_av_remove_entry(aTHX_ get_av(dl_modules, 0), dl_index);
+
+ return;
+}
+
+static int modperl_package_is_dynamic(pTHX_ const char *package,
+ I32 *dl_index)
+{
+ I32 i;
+ AV *modules = get_av(dl_modules, FALSE);
+
+ for (i=0; i<av_len(modules); i++) {
+ SV *module = *av_fetch(modules, i, 0);
+ if (strEQ(package, SvPVX(module))) {
+ *dl_index = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+modperl_cleanup_data_t *modperl_cleanup_data_new(apr_pool_t *p, void *data)
+{
+ modperl_cleanup_data_t *cdata =
+ (modperl_cleanup_data_t *)apr_pcalloc(p, sizeof(*cdata));
+ cdata->pool = p;
+ cdata->data = data;
+ return cdata;
+}
+
+MP_INLINE void modperl_perl_av_push_elts_ref(pTHX_ AV *dst, AV *src)
+{
+ I32 i, j, src_fill = AvFILLp(src), dst_fill = AvFILLp(dst);
+
+ av_extend(dst, src_fill);
+ AvFILLp(dst) += src_fill+1;
+
+ for (i=dst_fill+1, j=0; j<=AvFILLp(src); i++, j++) {
+ AvARRAY(dst)[i] = SvREFCNT_inc(AvARRAY(src)[j]);
+ }
+}
+
+/*
+ * similar to hv_fetch_ent, but takes string key and key len rather than SV
+ * also skips magic and utf8 fu, since we are only dealing with internal tables
+ */
+HE *modperl_perl_hv_fetch_he(pTHX_ HV *hv,
+ register char *key,
+ register I32 klen,
+ register U32 hash)
+{
+ register XPVHV *xhv;
+ register HE *entry;
+
+ xhv = (XPVHV *)SvANY(hv);
+ if (!HvARRAY(hv)) {
+ return 0;
+ }
+
+#ifdef HvREHASH
+ if (HvREHASH(hv)) {
+ PERL_HASH_INTERNAL(hash, key, klen);
+ }
+ else
+#endif
+ if (!hash) {
+ PERL_HASH(hash, key, klen);
+ }
+
+ entry = ((HE**)HvARRAY(hv))[hash & (I32)xhv->xhv_max];
+
+ for (; entry; entry = HeNEXT(entry)) {
+ if (HeHASH(entry) != hash) {
+ continue;
+ }
+ if (HeKLEN(entry) != klen) {
+ continue;
+ }
+ if (HeKEY(entry) != key && memNE(HeKEY(entry), key, klen)) {
+ continue;
+ }
+ return entry;
+ }
+
+ return 0;
+}
+
+void modperl_str_toupper(char *str)
+{
+ while (*str) {
+ *str = apr_toupper(*str);
+ ++str;
+ }
+}
+
+/* XXX: same as Perl_do_sprintf();
+ * but Perl_do_sprintf() is not part of the "public" api
+ */
+void modperl_perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg)
+{
+ STRLEN patlen;
+ char *pat = SvPV(*sarg, patlen);
+ bool do_taint = FALSE;
+
+ sv_vsetpvfn(sv, pat, patlen, (va_list *)NULL, sarg + 1, len - 1, &do_taint);
+ SvSETMAGIC(sv);
+ if (do_taint) {
+ SvTAINTED_on(sv);
+ }
+}
+
+void modperl_perl_call_list(pTHX_ AV *subs, const char *name)
+{
+ I32 i, oldscope = PL_scopestack_ix;
+ SV **ary = AvARRAY(subs);
+
+ MP_TRACE_g(MP_FUNC, MP_TRACEf_PERLID
+ " running %d %s subs", MP_TRACEv_PERLID_
+ AvFILLp(subs)+1, name);
+
+ for (i=0; i<=AvFILLp(subs); i++) {
+ CV *cv = (CV*)ary[i];
+ SV *atsv = ERRSV;
+
+ PUSHMARK(PL_stack_sp);
+ call_sv((SV*)cv, G_EVAL|G_DISCARD);
+
+ if (SvCUR(atsv)) {
+ Perl_sv_catpvf(aTHX_ atsv, "%s failed--call queue aborted",
+ name);
+ while (PL_scopestack_ix > oldscope) {
+ LEAVE;
+ }
+ Perl_croak(aTHX_ "%s", SvPVX(atsv));
+ }
+ }
+}
+
+void modperl_perl_exit(pTHX_ int status)
+{
+ ENTER;
+ SAVESPTR(PL_diehook);
+ PL_diehook = (SV *)NULL;
+ modperl_croak(aTHX_ MODPERL_RC_EXIT, "ModPerl::Util::exit");
+}
+
+MP_INLINE SV *modperl_dir_config(pTHX_ request_rec *r, server_rec *s,
+ char *key, SV *sv_val)
+{
+ SV *retval = &PL_sv_undef;
+
+ if (r && r->per_dir_config) {
+ MP_dDCFG;
+ retval = modperl_table_get_set(aTHX_ dcfg->configvars,
+ key, sv_val, FALSE);
+ }
+
+ if (!SvOK(retval)) {
+ if (s && s->module_config) {
+ MP_dSCFG(s);
+ SvREFCNT_dec(retval); /* in case above did newSV(0) */
+ retval = modperl_table_get_set(aTHX_ scfg->configvars,
+ key, sv_val, FALSE);
+ }
+ else {
+ retval = &PL_sv_undef;
+ }
+ }
+
+ return retval;
+}
+
+SV *modperl_table_get_set(pTHX_ apr_table_t *table, char *key,
+ SV *sv_val, int do_taint)
+{
+ SV *retval = &PL_sv_undef;
+
+ if (table == NULL) {
+ /* do nothing */
+ }
+ else if (key == NULL) {
+ retval = modperl_hash_tie(aTHX_ "APR::Table",
+ (SV *)NULL, (void*)table);
+ }
+ else if (!sv_val) { /* no val was passed */
+ char *val;
+ if ((val = (char *)apr_table_get(table, key))) {
+ retval = newSVpv(val, 0);
+ }
+ else {
+ retval = newSV(0);
+ }
+ if (do_taint) {
+ SvTAINTED_on(retval);
+ }
+ }
+ else if (!SvOK(sv_val)) { /* val was passed in as undef */
+ apr_table_unset(table, key);
+ }
+ else {
+ apr_table_set(table, key, SvPV_nolen(sv_val));
+ }
+
+ return retval;
+}
+
+static char *package2filename(const char *package, int *len)
+{
+ const char *s;
+ char *d;
+ char *filename;
+
+ filename = malloc((strlen(package)+4)*sizeof(char));
+
+ for (s = package, d = filename; *s; s++, d++) {
+ if (*s == ':' && s[1] == ':') {
+ *d = '/';
+ s++;
+ }
+ else {
+ *d = *s;
+ }
+ }
+ *d++ = '.';
+ *d++ = 'p';
+ *d++ = 'm';
+ *d = '\0';
+
+ *len = d - filename;
+ return filename;
+}
+
+MP_INLINE int modperl_perl_module_loaded(pTHX_ const char *name)
+{
+ SV **svp;
+ int len;
+ char *filename = package2filename(name, &len);
+ svp = hv_fetch(GvHVn(PL_incgv), filename, len, 0);
+ free(filename);
+
+ return (svp && *svp != &PL_sv_undef) ? 1 : 0;
+}
+
+#define SLURP_SUCCESS(action) \
+ if (rc != APR_SUCCESS) { \
+ SvREFCNT_dec(sv); \
+ modperl_croak(aTHX_ rc, \
+ apr_psprintf(r->pool, \
+ "slurp_filename('%s') / " action, \
+ r->filename)); \
+ }
+
+MP_INLINE SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted)
+{
+ SV *sv;
+ apr_status_t rc;
+ apr_size_t size;
+ apr_file_t *file;
+
+ size = r->finfo.size;
+ sv = newSV(size);
+
+ /* XXX: could have checked whether r->finfo.filehand is valid and
+ * save the apr_file_open call, but apache gives us no API to
+ * check whether filehand is valid. we can't test whether it's
+ * NULL or not, as it may contain garbagea
+ */
+ rc = apr_file_open(&file, r->filename, APR_READ|APR_BINARY,
+ APR_OS_DEFAULT, r->pool);
+ SLURP_SUCCESS("opening");
+
+ rc = apr_file_read(file, SvPVX(sv), &size);
+ SLURP_SUCCESS("reading");
+
+ MP_TRACE_o(MP_FUNC, "read %d bytes from '%s'", size, r->filename);
+
+ if (r->finfo.size != size) {
+ SvREFCNT_dec(sv);
+ Perl_croak(aTHX_ "Error: read %d bytes, expected %d ('%s')",
+ size, (apr_size_t)r->finfo.size, r->filename);
+ }
+
+ rc = apr_file_close(file);
+ SLURP_SUCCESS("closing");
+
+ SvPVX(sv)[size] = '\0';
+ SvCUR_set(sv, size);
+ SvPOK_on(sv);
+
+ if (tainted) {
+ SvTAINTED_on(sv);
+ }
+ else {
+ SvTAINTED_off(sv);
+ }
+
+ return newRV_noinc(sv);
+}
+
+#define MP_VALID_PKG_CHAR(c) (isalnum(c) ||(c) == '_')
+#define MP_VALID_PATH_DELIM(c) ((c) == '/' || (c) =='\\')
+char *modperl_file2package(apr_pool_t *p, const char *file)
+{
+ char *package;
+ char *c;
+ const char *f;
+ int len = strlen(file)+1;
+
+ /* First, skip invalid prefix characters */
+ while (!MP_VALID_PKG_CHAR(*file)) {
+ file++;
+ len--;
+ }
+
+ /* Then figure out how big the package name will be like */
+ for (f = file; *f; f++) {
+ if (MP_VALID_PATH_DELIM(*f)) {
+ len++;
+ }
+ }
+
+ package = apr_pcalloc(p, len);
+
+ /* Then, replace bad characters with '_' */
+ for (c = package; *file; c++, file++) {
+ if (MP_VALID_PKG_CHAR(*file)) {
+ *c = *file;
+ }
+ else if (MP_VALID_PATH_DELIM(*file)) {
+
+ /* Eliminate subsequent duplicate path delim */
+ while (*(file+1) && MP_VALID_PATH_DELIM(*(file+1))) {
+ file++;
+ }
+
+ /* path delim not until end of line */
+ if (*(file+1)) {
+ *c = *(c+1) = ':';
+ c++;
+ }
+ }
+ else {
+ *c = '_';
+ }
+ }
+
+ return package;
+}
+
+SV *modperl_apr_array_header2avrv(pTHX_ apr_array_header_t *array)
+{
+ AV *av = newAV();
+
+ if (array) {
+ int i;
+ for (i = 0; i < array->nelts; i++) {
+ av_push(av, newSVpv(((char **)array->elts)[i], 0));
+ }
+ }
+ return newRV_noinc((SV*)av);
+}
+
+apr_array_header_t *modperl_avrv2apr_array_header(pTHX_ apr_pool_t *p,
+ SV *avrv)
+{
+ AV *av;
+ apr_array_header_t *array;
+ int i, av_size;
+
+ if (!(SvROK(avrv) && (SvTYPE(SvRV(avrv)) == SVt_PVAV))) {
+ Perl_croak(aTHX_ "Not an array reference");
+ }
+
+ av = (AV*)SvRV(avrv);
+ av_size = av_len(av);
+ array = apr_array_make(p, av_size+1, sizeof(char *));
+
+ for (i = 0; i <= av_size; i++) {
+ SV *sv = *av_fetch(av, i, FALSE);
+ char **entry = (char **)apr_array_push(array);
+ *entry = apr_pstrdup(p, SvPV_nolen(sv));
+ }
+
+ return array;
+}
+
+/* Remove a package from %INC */
+static void modperl_package_delete_from_inc(pTHX_ const char *package)
+{
+ int len;
+ char *filename = package2filename(package, &len);
+ (void)hv_delete(GvHVn(PL_incgv), filename, len, G_DISCARD);
+ free(filename);
+}
+
+/* Destroy a package's stash */
+#define MP_STASH_SUBSTASH(key, len) ((len >= 2) && \
+ (key[len-1] == ':') && \
+ (key[len-2] == ':'))
+#define MP_STASH_DEBUGGER(key, len) ((len >= 2) && \
+ (key[0] == '_') && \
+ (key[1] == '<'))
+#define MP_SAFE_STASH(key, len) (!(MP_STASH_SUBSTASH(key,len)|| \
+ (MP_STASH_DEBUGGER(key, len))))
+static void modperl_package_clear_stash(pTHX_ const char *package)
+{
+ HV *stash;
+ if ((stash = gv_stashpv(package, FALSE))) {
+ HE *he;
+ I32 len;
+ char *key;
+ hv_iterinit(stash);
+ while ((he = hv_iternext(stash))) {
+ key = hv_iterkey(he, &len);
+ if (MP_SAFE_STASH(key, len)) {
+ SV *val = hv_iterval(stash, he);
+ /* The safe thing to do is to skip over stash entries
+ * that don't come from the package we are trying to
+ * unload
+ */
+ if (GvSTASH(val) == stash) {
+ (void)hv_delete(stash, key, len, G_DISCARD);
+ }
+ }
+ }
+ }
+}
+
+/* Unload a module as completely and cleanly as possible */
+void modperl_package_unload(pTHX_ const char *package)
+{
+ I32 dl_index;
+
+ modperl_package_clear_stash(aTHX_ package);
+ modperl_package_delete_from_inc(aTHX_ package);
+
+ if (modperl_package_is_dynamic(aTHX_ package, &dl_index)) {
+ modperl_package_unload_dynamic(aTHX_ package, dl_index);
+ }
+
+}
+
+#define MP_RESTART_COUNT_KEY "mod_perl_restart_count"
+
+/* passing the main server object here, just because we don't have the
+ * modperl_server_pool available yet, later on we can access it
+ * through the modperl_server_pool() call.
+ */
+void modperl_restart_count_inc(server_rec *base_server)
+{
+ void *data;
+ int *counter;
+ apr_pool_t *p = base_server->process->pool;
+
+ apr_pool_userdata_get(&data, MP_RESTART_COUNT_KEY, p);
+ if (data) {
+ counter = data;
+ (*counter)++;
+ }
+ else {
+ counter = apr_palloc(p, sizeof *counter);
+ *counter = 1;
+ apr_pool_userdata_set(counter, MP_RESTART_COUNT_KEY,
+ apr_pool_cleanup_null, p);
+ }
+}
+
+int modperl_restart_count(void)
+{
+ void *data;
+ apr_pool_userdata_get(&data, MP_RESTART_COUNT_KEY,
+ modperl_global_get_server_rec()->process->pool);
+ return data ? *(int *)data : 0;
+ }
+
+static MP_INLINE
+apr_status_t modperl_cleanup_pnotes(void *data) {
+ modperl_pnotes_t *pnotes = data;
+
+ dTHXa(pnotes->interp->perl);
+ MP_ASSERT_CONTEXT(aTHX);
+
+ SvREFCNT_dec(pnotes->pnotes);
+ pnotes->pnotes = NULL;
+ pnotes->pool = NULL;
+
+ MP_INTERP_PUTBACK(pnotes->interp, aTHX);
+ return APR_SUCCESS;
+}
+
+void modperl_pnotes_kill(void *data) {
+ modperl_pnotes_t *pnotes = data;
+
+ if( !pnotes->pnotes ) return;
+
+ apr_pool_cleanup_kill(pnotes->pool, pnotes, modperl_cleanup_pnotes);
+ modperl_cleanup_pnotes(pnotes);
+}
+
+SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val,
+ apr_pool_t *pool) {
+ SV *retval = (SV *)NULL;
+
+ if (!pnotes->pnotes) {
+ pnotes->pool = pool;
+#ifdef USE_ITHREADS
+ pnotes->interp = modperl_thx_interp_get(aTHX);
+ pnotes->interp->refcnt++;
+ MP_TRACE_i(MP_FUNC, "TO: (0x%lx)->refcnt incremented to %ld",
+ pnotes->interp, pnotes->interp->refcnt);
+#endif
+ pnotes->pnotes = newHV();
+ apr_pool_cleanup_register(pool, pnotes,
+ modperl_cleanup_pnotes,
+ apr_pool_cleanup_null);
+ }
+
+ if (key) {
+ STRLEN len;
+ char *k = SvPV(key, len);
+
+ if (val) {
+ retval = *hv_store(pnotes->pnotes, k, len, SvREFCNT_inc(val), 0);
+ }
+ else if (hv_exists(pnotes->pnotes, k, len)) {
+ retval = *hv_fetch(pnotes->pnotes, k, len, FALSE);
+ }
+
+ return retval ? SvREFCNT_inc(retval) : &PL_sv_undef;
+ }
+ return newRV_inc((SV *)pnotes->pnotes);
+}
+
+U16 *modperl_code_attrs(pTHX_ CV *cv) {
+ MAGIC *mg;
+
+ if (!(SvMAGICAL(cv) && (mg = mg_find((SV*)cv, PERL_MAGIC_ext)))) {
+ sv_magic((SV*)cv, (SV *)NULL, PERL_MAGIC_ext, NULL, -1);
+ }
+
+ mg = mg_find((SV*)cv, PERL_MAGIC_ext);
+ return &(mg->mg_private);
+}
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+
+static apr_hash_t *global_authz_providers = NULL;
+static apr_hash_t *global_authn_providers = NULL;
+
+typedef struct {
+ SV *cb1;
+ SV *cb2;
+ modperl_handler_t *cb1_handler;
+ modperl_handler_t *cb2_handler;
+} auth_callback;
+
+static apr_status_t cleanup_perl_global_providers(void *ctx)
+{
+ global_authz_providers = NULL;
+ global_authn_providers = NULL;
+ return APR_SUCCESS;
+}
+
+static authz_status perl_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_status ret = AUTHZ_DENIED;
+ int count;
+ AV *args = (AV *)NULL;
+ const char *key;
+ auth_callback *ab;
+ MP_dINTERPa(r, NULL, NULL);
+
+ if (global_authz_providers == NULL) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ key = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
+ ab = apr_hash_get(global_authz_providers, key, APR_HASH_KEY_STRING);
+ if (ab == NULL) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ if (ab->cb1 == NULL) {
+ if (ab->cb1_handler == NULL) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ modperl_handler_make_args(aTHX_ &args, "Apache2::RequestRec", r,
+ "PV", require_args, NULL);
+ ret = modperl_callback(aTHX_ ab->cb1_handler, r->pool, r, r->server,
+ args);
+ SvREFCNT_dec((SV*)args);
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ {
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r)));
+ XPUSHs(sv_2mortal(newSVpv(require_args, 0)));
+ PUTBACK;
+ count = call_sv(ab->cb1, G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ ret = (authz_status) POPi;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+}
+
+static const char *perl_parse_require_line(cmd_parms *cmd,
+ const char *require_line,
+ const void **parsed_require_line)
+{
+ char *ret = NULL;
+ void *key;
+ auth_callback *ab;
+
+ if (global_authz_providers == NULL ||
+ apr_hash_count(global_authz_providers) == 0)
+ {
+ return NULL;
+ }
+
+ apr_pool_userdata_get(&key, AUTHZ_PROVIDER_NAME_NOTE, cmd->temp_pool);
+ ab = apr_hash_get(global_authz_providers, (char *) key, APR_HASH_KEY_STRING);
+ if (ab == NULL || ab->cb2 == NULL) {
+ return NULL;
+ }
+
+ {
+ /* PerlAddAuthzProvider currently does not support an optional second
+ * handler, so ab->cb2 should always be NULL above and we will never get
+ * here. If such support is added in the future then this code will be
+ * reached, but cannot succeed in the absence of an interpreter. The
+ * second handler would be called at init to check a Require line for
+ * errors, but in the current design there is no interpreter available
+ * at that time.
+ */
+ MP_dINTERP_POOLa(cmd->pool, cmd->server);
+ if (!MP_HAS_INTERP(interp)) {
+ return "Require handler is not currently supported in this context";
+ }
+
+ {
+ SV *ret_sv;
+ int count;
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::CmdParms", cmd)));
+ XPUSHs(sv_2mortal(newSVpv(require_line, 0)));
+ PUTBACK;
+ count = call_sv(ab->cb2, G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ ret_sv = POPs;
+ if (SvOK(ret_sv)) {
+ char *tmp = SvPV_nolen(ret_sv);
+ if (*tmp != '\0') {
+ ret = apr_pstrdup(cmd->pool, tmp);
+ }
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+ }
+ return ret;
+}
+
+static authn_status perl_check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ authn_status ret = AUTH_DENIED;
+ int count;
+ AV *args = (AV *)NULL;
+ const char *key;
+ auth_callback *ab;
+ MP_dINTERPa(r, NULL, NULL);
+
+ if (global_authn_providers == NULL) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ key = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+ ab = apr_hash_get(global_authn_providers, key,
+ APR_HASH_KEY_STRING);
+ if (ab == NULL || ab->cb1) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ if (ab->cb1 == NULL) {
+ if (ab->cb1_handler == NULL) {
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ modperl_handler_make_args(aTHX_ &args, "Apache2::RequestRec", r,
+ "PV", user,
+ "PV", password, NULL);
+ ret = modperl_callback(aTHX_ ab->cb1_handler, r->pool, r, r->server,
+ args);
+ SvREFCNT_dec((SV*)args);
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+ }
+
+ {
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r)));
+ XPUSHs(sv_2mortal(newSVpv(user, 0)));
+ XPUSHs(sv_2mortal(newSVpv(password, 0)));
+ PUTBACK;
+ count = call_sv(ab->cb1, G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ ret = (authn_status) POPi;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+ return ret;
+}
+
+static authn_status perl_get_realm_hash(request_rec *r, const char *user,
+ const char *realm, char **rethash)
+{
+ authn_status ret = AUTH_USER_NOT_FOUND;
+ const char *key;
+ auth_callback *ab;
+
+ if (global_authn_providers == NULL ||
+ apr_hash_count(global_authn_providers) == 0)
+ {
+ return AUTH_GENERAL_ERROR;
+ }
+
+ key = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+ ab = apr_hash_get(global_authn_providers, key, APR_HASH_KEY_STRING);
+ if (ab == NULL || ab->cb2 == NULL) {
+ return AUTH_GENERAL_ERROR;
+ }
+
+ {
+ /* PerlAddAuthnProvider currently does not support an optional second
+ * handler, so ab->cb2 should always be NULL above and we will never get
+ * here. If such support is added in the future then this code will be
+ * reached. Unlike the PerlAddAuthzProvider case, the second handler here
+ * would be called during request_rec processing to obtain a password hash
+ * for the realm so there should be no problem grabbing an interpreter.
+ */
+ MP_dINTERPa(r, NULL, NULL);
+
+ {
+ SV* rh = sv_2mortal(newSVpv("", 0));
+ int count;
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r)));
+ XPUSHs(sv_2mortal(newSVpv(user, 0)));
+ XPUSHs(sv_2mortal(newSVpv(realm, 0)));
+ XPUSHs(newRV_noinc(rh));
+ PUTBACK;
+ count = call_sv(ab->cb2, G_SCALAR);
+ SPAGAIN;
+
+ if (count == 1) {
+ const char *tmp = SvPV_nolen(rh);
+ ret = (authn_status) POPi;
+ if (*tmp != '\0') {
+ *rethash = apr_pstrdup(r->pool, tmp);
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ MP_INTERP_PUTBACK(interp, aTHX);
+ }
+
+ return ret;
+}
+
+static const authz_provider authz_perl_provider = { perl_check_authorization,
+ perl_parse_require_line };
+
+static const authn_provider authn_perl_provider = { perl_check_password,
+ perl_get_realm_hash };
+
+static apr_status_t register_auth_provider(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_name,
+ const char *provider_version,
+ auth_callback *ab, int type)
+{
+ void *provider_ = NULL;
+
+ if (global_authz_providers == NULL) {
+ global_authz_providers = apr_hash_make(pool);
+ global_authn_providers = apr_hash_make(pool);
+ /* We have to use pre_cleanup here, otherwise this cleanup method
+ * would be called after another cleanup method which unloads
+ * mod_perl module.
+ */
+ apr_pool_pre_cleanup_register(pool, NULL,
+ cleanup_perl_global_providers);
+ }
+
+ if (strcmp(provider_group, AUTHZ_PROVIDER_GROUP) == 0) {
+ provider_ = (void *) &authz_perl_provider;
+ apr_hash_set(global_authz_providers, provider_name,
+ APR_HASH_KEY_STRING, ab);
+ }
+ else {
+ provider_ = (void *) &authn_perl_provider;
+ apr_hash_set(global_authn_providers, provider_name,
+ APR_HASH_KEY_STRING, ab);
+ }
+
+ return ap_register_auth_provider(pool, provider_group, provider_name,
+ provider_version, provider_, type);
+
+}
+
+apr_status_t modperl_register_auth_provider(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_name,
+ const char *provider_version,
+ SV *callback1, SV *callback2,
+ int type)
+{
+ char *provider_name_dup;
+ auth_callback *ab = NULL;
+
+ provider_name_dup = apr_pstrdup(pool, provider_name);
+ ab = apr_pcalloc(pool, sizeof(auth_callback));
+ ab->cb1 = callback1;
+ ab->cb2 = callback2;
+
+ return register_auth_provider(pool, provider_group, provider_name_dup,
+ provider_version, ab, type);
+}
+
+apr_status_t modperl_register_auth_provider_name(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_name,
+ const char *provider_version,
+ const char *callback1,
+ const char *callback2,
+ int type)
+{
+ char *provider_name_dup;
+ auth_callback *ab = NULL;
+
+ provider_name_dup = apr_pstrdup(pool, provider_name);
+ ab = apr_pcalloc(pool, sizeof(auth_callback));
+ ab->cb1_handler = modperl_handler_new(pool, callback1);
+ if (callback2) {
+ ab->cb2_handler = modperl_handler_new(pool, callback2);
+ }
+
+ return register_auth_provider(pool, provider_group, provider_name_dup,
+ provider_version, ab, type);
+}
+
+#endif /* httpd-2.4 */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/src/modules/perl/modperl_util.h b/2_0_13/src/modules/perl/modperl_util.h
new file mode 100644
index 0000000..83e51d4
--- /dev/null
+++ b/2_0_13/src/modules/perl/modperl_util.h
@@ -0,0 +1,168 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_UTIL_H
+#define MODPERL_UTIL_H
+
+#include "modperl_common_util.h"
+
+/* check whether the response phase has been initialized already */
+#define MP_CHECK_WBUCKET_INIT(func) \
+ if (!rcfg->wbucket) { \
+ Perl_croak(aTHX_ "%s: " func " can't be called " \
+ "before the response phase", MP_FUNC); \
+ }
+
+/* turn off cgi header parsing. in case we are already inside
+ * modperl_callback_per_dir(MP_RESPONSE_HANDLER, r, MP_HOOK_RUN_FIRST);
+ * but haven't sent any data yet, it's too late to change
+ * MpReqPARSE_HEADERS, so change the wbucket's private flag directly
+ */
+#define MP_CGI_HEADER_PARSER_OFF(rcfg) \
+ MpReqPARSE_HEADERS_Off(rcfg); \
+ if (rcfg->wbucket) { \
+ rcfg->wbucket->header_parse = 0; \
+ }
+
+MP_INLINE server_rec *modperl_sv2server_rec(pTHX_ SV *sv);
+MP_INLINE request_rec *modperl_sv2request_rec(pTHX_ SV *sv);
+
+request_rec *modperl_xs_sv2request_rec(pTHX_ SV *sv, char *classname, CV *cv);
+
+MP_INLINE SV *modperl_newSVsv_obj(pTHX_ SV *stashsv, SV *obj);
+
+MP_INLINE SV *modperl_ptr2obj(pTHX_ char *classname, void *ptr);
+
+int modperl_errsv(pTHX_ int status, request_rec *r, server_rec *s);
+
+void modperl_errsv_prepend(pTHX_ const char *pat, ...);
+
+int modperl_require_module(pTHX_ const char *pv, int logfailure);
+int modperl_require_file(pTHX_ const char *pv, int logfailure);
+
+void modperl_xs_dl_handles_clear(pTHX);
+
+void **modperl_xs_dl_handles_get(pTHX);
+
+void modperl_xs_dl_handles_close(void **handles);
+
+modperl_cleanup_data_t *modperl_cleanup_data_new(apr_pool_t *p, void *data);
+
+MP_INLINE void modperl_perl_av_push_elts_ref(pTHX_ AV *dst, AV *src);
+
+HE *modperl_perl_hv_fetch_he(pTHX_ HV *hv,
+ register char *key,
+ register I32 klen,
+ register U32 hash);
+
+#define hv_fetch_he(hv,k,l,h) \
+ modperl_perl_hv_fetch_he(aTHX_ hv, k, l, h)
+
+void modperl_str_toupper(char *str);
+
+void modperl_perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg);
+
+void modperl_perl_call_list(pTHX_ AV *subs, const char *name);
+
+void modperl_perl_exit(pTHX_ int status);
+
+MP_INLINE SV *modperl_dir_config(pTHX_ request_rec *r, server_rec *s,
+ char *key, SV *sv_val);
+
+SV *modperl_table_get_set(pTHX_ apr_table_t *table, char *key,
+ SV *sv_val, int do_taint);
+
+MP_INLINE int modperl_perl_module_loaded(pTHX_ const char *name);
+
+/**
+ * slurp the contents of r->filename and return them as a scalar
+ * @param r request record
+ * @param tainted whether the SV should be marked tainted or not
+ * @return a PV scalar with the contents of the file
+ */
+SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted);
+
+char *modperl_file2package(apr_pool_t *p, const char *file);
+
+SV *modperl_apr_array_header2avrv(pTHX_ apr_array_header_t *array);
+apr_array_header_t *modperl_avrv2apr_array_header(pTHX_ apr_pool_t *p,
+ SV *avrv);
+void modperl_package_unload(pTHX_ const char *package);
+#if defined(MP_TRACE) && defined(USE_ITHREADS)
+#define MP_TRACEf_PERLID "perl id 0x%lx"
+#define MP_TRACEv_PERLID (unsigned long)my_perl
+#define MP_TRACEv_PERLID_ MP_TRACEv_PERLID,
+#define MP_TRACEv__PERLID ,MP_TRACEv_PERLID
+#else
+#define MP_TRACEf_PERLID
+#define MP_TRACEv_PERLID
+#define MP_TRACEv_PERLID_
+#define MP_TRACEv__PERLID
+#endif /* USE_ITHREADS */
+
+/* dumping hundreds of lines in the trace, makes it less useful. Get a
+ * string chunk of MP_TRACE_STR_LEN bytes or less. Not too long so it
+ * won't wrap when posted in email. Notice that we copy 'count' bytes
+ * of the string even if count < MP_TRACE_STR_LEN, because the 'str'
+ * buffer doesn't necessarily have \0 terminator at 'count'. As this
+ * is for debug tracing, not to be used in production, it doesn't make
+ * any difference if it's not efficient.
+ */
+#define MP_TRACE_STR_LEN 35
+#define MP_TRACE_STR_TRUNC(p, str, count) \
+ count < MP_TRACE_STR_LEN \
+ ? (char *)apr_pstrmemdup(p, str, count) \
+ : (char *)apr_psprintf(p, "%s...", \
+ apr_pstrmemdup(p, str, MP_TRACE_STR_LEN))
+
+/* functions maintaining the amount of times mod_perl was restarted,
+ * e.g. on Apache start, it restarts itself, so the count will be
+ * first 1, and on on restart 2 */
+void modperl_restart_count_inc(server_rec *base_server);
+int modperl_restart_count(void);
+
+void modperl_pnotes_kill(void *data);
+
+SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val,
+ apr_pool_t *pool );
+
+U16 *modperl_code_attrs(pTHX_ CV *cv);
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+apr_status_t
+modperl_register_auth_provider(apr_pool_t *pool, const char *provider_group,
+ const char *provider_name,
+ const char *provider_version, SV *callback1,
+ SV *callback2, int type);
+
+apr_status_t
+modperl_register_auth_provider_name(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_name,
+ const char *provider_version,
+ const char *callback1,
+ const char *callback2, int type);
+#endif
+
+#endif /* MODPERL_UTIL_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/t/apache/add_config.t b/2_0_13/t/apache/add_config.t
new file mode 100644
index 0000000..90edaec
--- /dev/null
+++ b/2_0_13/t/apache/add_config.t
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# the handler is configured in modperl_extra.pl via
+# Apache2::ServerUtil->server->add_config
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+print GET_BODY_ASSERT "/apache/add_config";
diff --git a/2_0_13/t/apache/cgihandler.t b/2_0_13/t/apache/cgihandler.t
new file mode 100644
index 0000000..ace671c
--- /dev/null
+++ b/2_0_13/t/apache/cgihandler.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 2;
+
+my $location = "/TestApache__cgihandler";
+
+my $expected = "1..3\nok 1\nok 2\nok 3\n";
+
+my $received = POST_BODY $location, content => $expected;
+
+ok t_cmp $received, $expected, "POST cgihandler";
+
+$received = GET_BODY $location;
+
+ok t_cmp $received, $expected, "GET cgihandler";
diff --git a/2_0_13/t/apache/constants.t b/2_0_13/t/apache/constants.t
new file mode 100644
index 0000000..81fe6aa
--- /dev/null
+++ b/2_0_13/t/apache/constants.t
@@ -0,0 +1,84 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use ExtUtils::testlib;
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+# -compile puts constants into the Apache2:: namespace
+use Apache2::Const -compile => qw(:http :common :mpmq :proxy
+ TAKE23 &OPT_EXECCGI
+ DECLINE_CMD DIR_MAGIC_TYPE
+ CRLF);
+
+# without -compile, constants are in the
+# caller namespace. also defaults to :common
+use Apache2::Const;
+
+plan tests => 18;
+
+ok t_cmp(REDIRECT, 302, 'REDIRECT');
+
+ok t_cmp(AUTH_REQUIRED, 401, 'AUTH_REQUIRED');
+
+ok t_cmp(OK, 0, 'OK');
+
+ok t_cmp(Apache2::Const::OK, 0, 'Apache2::Const::OK');
+
+ok t_cmp(Apache2::Const::DECLINED, -1, 'Apache2::Const::DECLINED');
+
+ok t_cmp(Apache2::Const::HTTP_GONE, 410, 'Apache2::Const::HTTP_GONE');
+
+ok t_cmp(Apache2::Const::DIR_MAGIC_TYPE,
+ 'httpd/unix-directory',
+ 'Apache2::Const::DIR_MAGIC_TYPE');
+
+ok t_cmp(Apache2::Const::MPMQ_MAX_SPARE_DAEMONS,
+ 9,
+ 'Apache2::Const::MPMQ_MAX_SPARE_DAEMONS');
+
+ok t_cmp(Apache2::Const::PROXYREQ_REVERSE,
+ 2,
+ 'Apache2::Const::PROXYREQ_REVERSE');
+
+# the rest of the tests don't fit into the t_cmp() meme
+# for one reason or anothre...
+
+print "testing Apache2::Const::OPT_EXECCGI is defined\n";
+ok defined Apache2::Const::OPT_EXECCGI;
+
+print "testing Apache2::Const::DECLINE_CMD\n";
+ok Apache2::Const::DECLINE_CMD eq "\x07\x08";
+
+# try and weed out EBCDIC - this is the test httpd uses
+if (chr(0xC1) eq 'A') {
+ print "testing Apache2::Const::CRLF (EBCDIC)\n";
+ ok Apache2::Const::CRLF eq "\r\n";
+}
+else {
+ print "testing Apache2::Const::CRLF (ASCII)\n";
+ ok Apache2::Const::CRLF eq "\015\012";
+
+}
+
+print "testing M_GET not yet defined\n";
+ok ! defined &M_GET;
+
+Apache2::Const->import('M_GET');
+
+print "testing M_GET now defined\n";
+ok defined &M_GET;
+
+for (qw(BOGUS :bogus -foobar)) {
+
+ eval { Apache2::Const->import($_) };
+
+ print "testing bogus import $_\n";
+ ok $@;
+}
+
+print "testing explicit call to compile()\n";
+eval { Apache2::Const::compile() };
+
+ok $@;
diff --git a/2_0_13/t/apache/content_length_header.t b/2_0_13/t/apache/content_length_header.t
new file mode 100644
index 0000000..2b414e4
--- /dev/null
+++ b/2_0_13/t/apache/content_length_header.t
@@ -0,0 +1,158 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 12 * 2 + 3;
+
+my $location = "/TestApache__content_length_header";
+
+# 1. because Apache proclaims itself governor of the C-L header via
+# the C-L filter (ap_content_length_filter at
+# httpd-2.0/server/protocol.c), test whether GET and HEAD behave the
+# same wrt C-L under varying circumstances. for the most part GET
+# and HEAD should behave exactly the same. however, when Apache
+# sees a HEAD request with a C-L header of zero it takes special
+# action and removes the C-L header. this is done to protect against
+# handlers that called r->header_only (which was ok in 1.3 but is
+# not in 2.0). So, GET and HEAD behave the same except when the
+# content handler (plus filters) end up sending no content. see
+# the lengthy comments in ap_http_header_filter in http_protocol.c.
+#
+# for more discussion on
+# why it is important to get HEAD requests right, see these threads
+# from the mod_perl list
+# http://marc.theaimsgroup.com/?l=apache-modperl&m=108647669726915&w=2
+# http://marc.theaimsgroup.com/?t=109122984600001&r=1&w=2
+# as well as this bug report from mozilla, which shows how they
+# are using HEAD requests in the wild
+# http://bugzilla.mozilla.org/show_bug.cgi?id=245447
+
+foreach my $method (qw(GET HEAD)) {
+
+ no strict qw(refs);
+
+ {
+ # if the response handler sends no data, and sets no C-L header,
+ # the client doesn't get C-L header at all.
+ #
+ # in 2.0 GET requests get a C-L of zero, while HEAD requests do
+ # not due to special processing.
+ my $uri = $location;
+ my $res = $method->($uri);
+
+ my $cl = 0;
+ my $head_cl = undef;
+
+ ok t_cmp $res->code, 200, "$method $uri code";
+ ok t_cmp ($res->header('Content-Length'),
+ $method eq 'GET' ? $cl : $head_cl,
+ "$method $uri C-L header");
+ ok t_cmp $res->content, "", "$method $uri content";
+ }
+
+ {
+ # if the response handler sends no data and sets C-L header,
+ # the client should receive the set content length. in 2.1
+ # this is the way it happens. see protocol.c -r1.150 -r1.151
+ #
+ # in 2.0 the client doesn't get C-L header for HEAD requests
+ # due to special processing, and GET requests get a calculated
+ # C-L of zero.
+ my $uri = "$location?set_content_length";
+ my $res = $method->($uri);
+
+ my $cl = 0;
+ my $head_cl;
+
+ ## 2.2.1, 2.0.56, 2.0.57 were not released
+ ## but we use the versions the changes went into
+ ## to protect against wierd SVN checkout building.
+ ## XXX: I'm starting to think this test is more
+ ## trouble then its worth.
+ if (have_min_apache_version("2.2.1")) {
+ $head_cl = 25;
+ }
+ elsif (have_min_apache_version("2.2.0")) {
+ # $head_cl = undef; # avoid warnings
+ }
+ elsif (have_min_apache_version("2.0.56")) {
+ $head_cl = 25;
+ }
+ else {
+ # $head_cl = undef; # avoid warnings
+ }
+
+ ok t_cmp $res->code, 200, "$method $uri code";
+ ok t_cmp ($res->header('Content-Length'),
+ $method eq 'GET' ? $cl : $head_cl,
+ "$method $uri C-L header");
+ ok t_cmp $res->content, "", "$method $uri content";
+ }
+
+ {
+ # if the response handler sends data, and sets no C-L header,
+ # the client doesn't get C-L header.
+ my $uri = "$location?send_body";
+ my $res = $method->($uri);
+ ok t_cmp $res->code, 200, "$method $uri code";
+ ok t_cmp $res->header('Content-Length'), undef,
+ "$method $uri C-L header";
+
+ my $content = $method eq 'GET' ? 'This is a response string' : '';
+ ok t_cmp $res->content, $content, "$method $uri content";
+ }
+
+ {
+ # if the response handler sends data (e.g. one char string), and
+ # sets C-L header, the client gets the C-L header
+ my $uri = "$location?send_body+set_content_length";
+ my $res = $method->($uri);
+ ok t_cmp $res->code, 200, "$method $uri code";
+ ok t_cmp $res->header('Content-Length'), 25,
+ "$method $uri C-L header";
+
+ my $content = $method eq 'GET' ? 'This is a response string' : '';
+ ok t_cmp $res->content, $content, "$method $uri content";
+ }
+}
+
+# 2. even though the spec says that content handlers should send an
+# identical response for GET and HEAD requests, some folks try to
+# avoid the overhead of generating the response body, which Apache is
+# going to discard anyway for HEAD requests. The following discussion
+# assumes that we deal with a HEAD request.
+#
+# When Apache sees EOS and no headers and no response body were sent,
+# ap_content_length_filter (httpd-2.0/server/protocol.c) sets C-L to
+# 0. Later on ap_http_header_filter
+# (httpd-2.0/modules/http/http_protocol.c) removes the C-L header for
+# the HEAD requests
+#
+# the workaround is to force the sending of the response headers,
+# before EOS was sent. The simplest solution is to use rflush():
+#
+# if ($r->header_only) { # HEAD
+# $body_len = calculate_body_len();
+# $r->set_content_length($body_len);
+# $r->rflush;
+# }
+# else { # GET
+# # generate and send the body
+# }
+#
+# now if the handler sets the C-L header it'll be delivered to the
+# client unmodified.
+
+{
+ # if the response handler sends data (e.g. one char string), and
+ # sets C-L header, the client gets the C-L header
+ my $uri = "$location?head_no_body+set_content_length";
+ my $res = HEAD $uri;
+ ok t_cmp $res->code, 200, "HEAD $uri code";
+ ok t_cmp $res->header('Content-Length'), 25, "HEAD $uri C-L header";
+ ok t_cmp $res->content, '', "HEAD $uri content";
+}
diff --git a/2_0_13/t/apache/discard_rbody.t b/2_0_13/t/apache/discard_rbody.t
new file mode 100644
index 0000000..49caab0
--- /dev/null
+++ b/2_0_13/t/apache/discard_rbody.t
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+use Apache::TestRequest;
+
+my $location = "/TestApache__discard_rbody";
+my $content = "Y" x 100000; # more than one bucket
+
+plan tests => 3;
+
+for my $test (qw(none partial all)) {
+ my $received = POST_BODY "$location?$test", content => $content;
+ ok t_cmp($received, $test, "data consumption: $test");
+}
+
diff --git a/2_0_13/t/apache/post.t b/2_0_13/t/apache/post.t
new file mode 100644
index 0000000..ba0f573
--- /dev/null
+++ b/2_0_13/t/apache/post.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 2;
+
+my $location = "/TestApache__post";
+my $str;
+
+my @data = (arizona => 'wildcats');
+my %data = @data;
+
+$str = POST_BODY $location, content => "@data";
+
+ok $str;
+
+my $data = join '&', map { "$_=$data{$_}" } keys %data;
+
+$str = POST_BODY $location, content => $data;
+ok t_cmp($str,
+ join(':', length($data), $data),
+ "POST");
diff --git a/2_0_13/t/apache/read.t b/2_0_13/t/apache/read.t
new file mode 100644
index 0000000..9f7f504
--- /dev/null
+++ b/2_0_13/t/apache/read.t
@@ -0,0 +1,52 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catfile);
+
+plan tests => 1;
+
+#force test to go over http, since this doesn't work with t/TEST -ssl
+Apache::TestRequest::scheme('http');
+
+my $location = "/TestApache__read";
+
+my $socket = Apache::TestRequest::vhost_socket('default');
+
+my $file = catfile Apache::Test::vars('serverroot'), "..", 'Makefile';
+
+open my $fh, $file or die "open $file: $!";
+my $data = join '', <$fh>;
+close $fh;
+
+my $size = length $data;
+
+for my $string ("POST $location HTTP/1.0",
+ "Content-length: $size",
+ "") {
+ my $line = "$string\r\n";
+ syswrite $socket, $line, length($line);
+}
+
+my $written = 0;
+my $bufsiz = 240;
+
+my $sleeps = 2;
+
+while ($written < length($data)) {
+ my $remain = length($data) - $written;
+ my $len = $remain > $bufsiz ? $bufsiz : $remain;
+ $written += syswrite $socket, $data, $len, $written;
+ sleep 1 if $sleeps-- > 0;
+}
+
+while (<$socket>) {
+ last if /^\015?\012$/; #skip over headers
+}
+
+my $return = join '', <$socket>;
+
+ok $data eq $return;
diff --git a/2_0_13/t/apache/read2.t b/2_0_13/t/apache/read2.t
new file mode 100644
index 0000000..fc585d7
--- /dev/null
+++ b/2_0_13/t/apache/read2.t
@@ -0,0 +1,4 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::TestRequest 'POST_BODY_ASSERT';
+print POST_BODY_ASSERT "/TestApache__read2",
+ content => "foobar";
diff --git a/2_0_13/t/apache/read3.t b/2_0_13/t/apache/read3.t
new file mode 100644
index 0000000..e4fbee4
--- /dev/null
+++ b/2_0_13/t/apache/read3.t
@@ -0,0 +1,4 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::TestRequest 'POST_BODY_ASSERT';
+print POST_BODY_ASSERT "/TestApache__read3",
+ content => "foobar"x2000;
diff --git a/2_0_13/t/apache/read4.t b/2_0_13/t/apache/read4.t
new file mode 100644
index 0000000..eeb7341
--- /dev/null
+++ b/2_0_13/t/apache/read4.t
@@ -0,0 +1,4 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::TestRequest 'POST_BODY_ASSERT';
+print POST_BODY_ASSERT "/TestApache__read4",
+ content => "foobar"x2;
diff --git a/2_0_13/t/apache/scanhdrs.t b/2_0_13/t/apache/scanhdrs.t
new file mode 100644
index 0000000..da305c5
--- /dev/null
+++ b/2_0_13/t/apache/scanhdrs.t
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 4;
+
+my $module = 'TestApache::scanhdrs';
+my $location = "/" . Apache::TestRequest::module2path($module);
+
+my $res = GET $location;
+
+t_debug $res->as_string;
+
+ok t_cmp($res->content, qr/^ok 1$/m);
+
+ok t_cmp($res->header('Content-Type'),
+ 'text/test-output',
+ "standard header");
+
+ok t_cmp($res->header('X-Perl-Module'),
+ $module,
+ "custom header");
+
+ok t_cmp($res->message, qr/beer/);
diff --git a/2_0_13/t/apache/scanhdrs2.t b/2_0_13/t/apache/scanhdrs2.t
new file mode 100644
index 0000000..7956b84
--- /dev/null
+++ b/2_0_13/t/apache/scanhdrs2.t
@@ -0,0 +1,35 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 5, need 'HTML::HeadParser';
+
+my $module = 'TestApache__scanhdrs2';
+my $location = "/$module";
+
+my $redirect = 'http://perl.apache.org/';
+
+my $res = GET "$location?$redirect", redirect_ok => 0;
+
+ok t_cmp($res->header('Location')||'', $redirect,
+ "Location header");
+
+ok t_cmp($res->code, 302,
+ "status == 302");
+
+$redirect = '/index.html';
+
+$res = GET "$location?$redirect", redirect_ok => 0;
+
+ok t_cmp(!$res->header('Location'), 1,
+ "no Location header");
+
+ok t_cmp($res->code, 200,
+ "status == 200");
+
+ok t_cmp($res->content, qr{welcome to},
+ "content is index.html");
diff --git a/2_0_13/t/apache/send_cgi_header.t b/2_0_13/t/apache/send_cgi_header.t
new file mode 100644
index 0000000..6a2bd53
--- /dev/null
+++ b/2_0_13/t/apache/send_cgi_header.t
@@ -0,0 +1,32 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 4;
+
+my $location = "/TestApache__send_cgi_header";
+my $res = GET $location;
+
+ok t_cmp($res->header('X-Foo'),
+ 'X-Bar',
+ "header test");
+
+ok t_cmp($res->header('Set-Cookie'),
+ 'Bad Programmer, No cookie!',
+ "header test2");
+
+my $expected = "\0\0This not the end of the world\0\0\n";
+my $received = $res->content;
+
+ok t_cmp(length($received),
+ length($expected),
+ "body length test");
+
+# \000 aren't seen when printed
+ok t_cmp($received,
+ $expected,
+ "body content test");
diff --git a/2_0_13/t/api/access2.t b/2_0_13/t/api/access2.t
new file mode 100644
index 0000000..f106dcd
--- /dev/null
+++ b/2_0_13/t/api/access2.t
@@ -0,0 +1,39 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+if (!have_min_apache_version("2.4.0")) {
+
+plan tests => 6, need need_lwp, need_auth, need_access, 'mod_version.c',
+ 'HTML::HeadParser';
+
+my $location = "/TestAPI__access2";
+
+ok !GET_OK $location;
+
+my $rc = GET_RC $location;
+ok t_cmp $rc, 401, "no credentials passed";
+
+# bad user
+ok !GET_OK $location, username => 'root', password => '1234';
+
+# good user/bad pass
+ok !GET_OK $location, username => 'goo', password => 'foo';
+
+# good user/good pass
+ok GET_OK $location, username => 'goo', password => 'goopass';
+
+# any user/any pass POST works
+ok POST_OK $location, username => 'bar', password => 'goopass1',
+ content => "a";
+
+}
+else {
+
+plan tests => 1, need {"mod_perl is not compiled with httpd-2.2" => 0};
+
+}
diff --git a/2_0_13/t/api/access2_24.t b/2_0_13/t/api/access2_24.t
new file mode 100644
index 0000000..3852c04
--- /dev/null
+++ b/2_0_13/t/api/access2_24.t
@@ -0,0 +1,38 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+if (have_min_apache_version("2.4.0")) {
+
+plan tests => 6, need need_lwp, need_auth, need_access, 'mod_access_compat.c',
+ 'mod_version.c', 'HTML::HeadParser';
+
+my $location = "/TestAPI__access2";
+
+ok !GET_OK $location;
+
+my $rc = GET_RC $location;
+ok t_cmp $rc, 401, "no credentials passed";
+
+# bad user
+ok !GET_OK $location, username => 'root', password => '1234';
+
+# good user/bad pass
+ok !GET_OK $location, username => 'goo', password => 'foo';
+
+# good user/good pass
+ok GET_OK $location, username => 'goo', password => 'goopass';
+
+# any user/any pass POST works
+ok POST_OK $location, username => 'bar', password => 'goopass1',
+ content => "a";
+
+}
+else {
+
+plan tests => 1, need {"mod_perl is not compiled with httpd-2.4" => 0};
+
+}
diff --git a/2_0_13/t/api/add_config.t b/2_0_13/t/api/add_config.t
new file mode 100644
index 0000000..20a1b7a
--- /dev/null
+++ b/2_0_13/t/api/add_config.t
@@ -0,0 +1,14 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestAPI::add_config';
+my $url = Apache::TestRequest::module2url($module) . "/";
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
+
diff --git a/2_0_13/t/api/content_encoding.t b/2_0_13/t/api/content_encoding.t
new file mode 100644
index 0000000..d030f00
--- /dev/null
+++ b/2_0_13/t/api/content_encoding.t
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1, need_min_module_version("Compress::Zlib", "1.09");
+
+my $location = '/TestAPI__content_encoding';
+
+my $expected = 'This is a clear text';
+
+my $res = POST $location, content => $expected;
+
+my $received = $res->content;
+#t_debug($received);
+
+if ($res->header('Content-Encoding') =~ /gzip/) {
+ require Compress::Zlib;
+
+ # gzip already produces data in a network order, so no extra
+ # transformation seem to be necessary
+ $received = Compress::Zlib::memGunzip($received);
+}
+
+ok t_cmp $received, $expected, "Content-Encoding: gzip test";
+
diff --git a/2_0_13/t/api/custom_response.t b/2_0_13/t/api/custom_response.t
new file mode 100644
index 0000000..3986008
--- /dev/null
+++ b/2_0_13/t/api/custom_response.t
@@ -0,0 +1,49 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catfile);
+
+use Apache2::Const -compile => qw(FORBIDDEN);
+
+my $module = 'TestAPI::custom_response';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+my $file = catfile Apache::Test::vars('documentroot'),
+ qw(api custom_response.txt);
+
+open my $fh, $file or die "Can't open $file: $!";
+my $data = do { binmode $fh; local $/; <$fh> };
+close $fh;
+
+plan tests => 4, need need_lwp, 'HTML::HeadParser';
+
+{
+ # custom text response
+ my $expected = "This_is_a_custom_text_response";
+ my $res = GET "$location?$expected";
+ ok t_cmp $res->code, Apache2::Const::FORBIDDEN, "custom text response (code)";
+ ok t_cmp $res->content, $expected, "custom text response (body)";
+}
+
+{
+ # custom relative url response
+ my $url = "/api/custom_response.txt";
+ my $res = GET "$location?$url";
+ ok t_cmp $res->content, $data, "custom file response (body)";
+}
+{
+ my $url = "http://$hostport/api/custom_response.txt";
+ # custom full url response
+ my $res = GET "$location?$url";
+ ok t_cmp $res->content, $data, "custom file response (body)";
+}
+
diff --git a/2_0_13/t/api/err_headers_out.t b/2_0_13/t/api/err_headers_out.t
new file mode 100644
index 0000000..a1eb446
--- /dev/null
+++ b/2_0_13/t/api/err_headers_out.t
@@ -0,0 +1,61 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 6, need 'HTML::HeadParser';
+
+my $location = '/TestAPI__err_headers_out';
+
+{
+ # with 2xx responses any of the err_headers_out and headers_out
+ # headers make it through
+
+ my $res = GET "$location?200";
+
+ #t_debug $res->as_string;
+
+ ok t_cmp $res->code, 200, "OK";
+
+ # HTTP::Headers 6.00 makes the next 2 tests fail. When the response comes
+ # in the header name is stored as "x-err_headers_out". But when it is to
+ # be read below it is referred as "x-err-headers-out" and hence not found.
+ local $HTTP::Headers::TRANSLATE_UNDERSCORE=
+ $HTTP::Headers::TRANSLATE_UNDERSCORE;
+ undef $HTTP::Headers::TRANSLATE_UNDERSCORE
+ if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION >= 6.00;
+
+ ok t_cmp $res->header('X-err_headers_out'), "err_headers_out",
+ "X-err_headers_out: made it";
+
+ ok t_cmp $res->header('X-headers_out'), "headers_out",
+ "X-headers_out: made it";
+}
+
+{
+ # with non-2xx responses only the err_headers_out headers make it
+ # through. the headers_out do not make it.
+
+ my $res = GET "$location?404";
+
+ #t_debug $res->as_string;
+
+ ok t_cmp $res->code, 404, "not found";
+
+ # HTTP::Headers 6.00 makes this test fail. When the response comes in
+ # the header name is stored as "x-err_headers_out". But when it is to
+ # be read below it is referred as "x-err-headers-out" and hence not found.
+ local $HTTP::Headers::TRANSLATE_UNDERSCORE=
+ $HTTP::Headers::TRANSLATE_UNDERSCORE;
+ undef $HTTP::Headers::TRANSLATE_UNDERSCORE
+ if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION >= 6.00;
+
+ ok t_cmp $res->header('X-err_headers_out'), "err_headers_out",
+ "X-err_headers_out: made it";
+
+ ok !$res->header('X-headers_out');
+}
+
diff --git a/2_0_13/t/api/in_out_filters.t b/2_0_13/t/api/in_out_filters.t
new file mode 100644
index 0000000..f9aa7a1
--- /dev/null
+++ b/2_0_13/t/api/in_out_filters.t
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $location = '/TestAPI__in_out_filters';
+
+my $content = join '', 'AA'..'ZZ', 1..99999;
+
+my $expected = lc $content;
+my $received = POST_BODY $location, content => $content;
+
+# don't use t_cmp in this test, because the data length is 500K.
+# You don't want to see 500K * 2 when you run t/TEST -verbose
+
+ok $received eq $expected;
+
diff --git a/2_0_13/t/api/internal_redirect.t b/2_0_13/t/api/internal_redirect.t
new file mode 100644
index 0000000..ecdd9bd
--- /dev/null
+++ b/2_0_13/t/api/internal_redirect.t
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# test internal redirects originating from 'SetHandler modperl' and
+# 'SetHandler perl-script' main handlers, and sub-requests handled by
+# the handlers of the same and the opposite kind
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $uri = "/TestAPI__internal_redirect";
+
+my %map = (
+ "modperl => modperl" => "${uri}_modperl?uri=${uri}_modperl",
+ "perl-script => modperl" => "${uri}_perl_script?uri=${uri}_modperl",
+ "perl-script => perl-script" => "${uri}_perl_script?uri=${uri}_perl_script",
+ "modperl => perl-script" => "${uri}_modperl?uri=${uri}_perl_script",
+);
+
+plan tests => scalar keys %map;
+
+while (my ($key, $val) = each %map) {
+ my $expected = "internal redirect: $key";
+ my $received = GET_BODY_ASSERT $val;
+ ok t_cmp($received, $expected);
+}
diff --git a/2_0_13/t/api/internal_redirect_handler.t b/2_0_13/t/api/internal_redirect_handler.t
new file mode 100644
index 0000000..26237d1
--- /dev/null
+++ b/2_0_13/t/api/internal_redirect_handler.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $uri = "/TestAPI__internal_redirect_handler";
+
+my @ct_types = qw(text/plain text/html);
+
+plan tests => scalar @ct_types;
+
+for my $type (@ct_types) {
+ my $expected = $type;
+ my $received = GET_BODY_ASSERT "$uri?ct=$type";
+ ok t_cmp $received, $expected, "Content-type: $type";
+}
diff --git a/2_0_13/t/api/lookup_misc.t b/2_0_13/t/api/lookup_misc.t
new file mode 100644
index 0000000..e73079b
--- /dev/null
+++ b/2_0_13/t/api/lookup_misc.t
@@ -0,0 +1,35 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use File::Spec;
+
+my $uri = "/TestAPI__lookup_misc";
+
+my $file = File::Spec->rel2abs(__FILE__);
+open my $fh, $file or die "Can't open $file: $!";
+my $data = do { binmode $fh; local $/; <$fh> };
+close $fh;
+
+plan tests => 2;
+
+# lookup_file
+{
+ my $args = "subreq=lookup_file;file=$file";
+ my $expected = $data;
+ my $received = GET_BODY_ASSERT "$uri?$args";
+ t_debug "lookup_file";
+ ok $received eq $expected;
+}
+
+# lookup_method_uri
+{
+ my $args = "subreq=lookup_method_uri;uri=/lookup_method_uri";
+ my $expected = "ok";
+ my $received = GET_BODY_ASSERT "$uri?$args";
+ ok t_cmp $received, $expected, "lookup_method_uri";
+}
diff --git a/2_0_13/t/api/lookup_uri.t b/2_0_13/t/api/lookup_uri.t
new file mode 100644
index 0000000..7864a01
--- /dev/null
+++ b/2_0_13/t/api/lookup_uri.t
@@ -0,0 +1,30 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $uri = "/TestAPI__lookup_uri";
+
+use constant PREFIX => 0;
+use constant SUFFIX => 1;
+
+my %opts = (
+ first => [2, 2], # all filters run twice
+ second => [1, 2], # the top level req filter skipped for the subreq
+ none => [1, 1], # no request filters run by subreq
+ default => [1, 1], # same as none
+);
+
+plan tests => scalar keys %opts;
+
+while (my ($filter, $runs) = each %opts) {
+ my $args = "subreq=lookup_uri;filter=$filter";
+ my $prefix = "pre+" x $runs->[PREFIX];
+ my $suffix = "+suf" x $runs->[SUFFIX];
+ my $expected = "$prefix$args$suffix";
+ my $received = GET_BODY_ASSERT "$uri?$args";
+ ok t_cmp $received, $expected, "$args";
+}
diff --git a/2_0_13/t/api/request_rec.t b/2_0_13/t/api/request_rec.t
new file mode 100644
index 0000000..f9163ab
--- /dev/null
+++ b/2_0_13/t/api/request_rec.t
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest 'GET_BODY_ASSERT';
+print GET_BODY_ASSERT "/TestAPI__request_rec/my_path_info?my_args=3";
diff --git a/2_0_13/t/api/rflush.t b/2_0_13/t/api/rflush.t
new file mode 100644
index 0000000..8f4fca0
--- /dev/null
+++ b/2_0_13/t/api/rflush.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+my $location = '/TestAPI__rflush';
+
+plan tests => 2;
+
+{
+ my $response = GET_BODY "$location?nontied";
+ ok t_cmp($response, "[1][2][3][4][56]",
+ "non-tied rflush creates bucket brigades");
+}
+
+{
+ my $response = GET_BODY "$location?tied";
+ ok t_cmp($response, "[1][2][3456]",
+ "tied STDOUT internal rflush creates bucket brigades");
+}
+
diff --git a/2_0_13/t/api/sendfile.t b/2_0_13/t/api/sendfile.t
new file mode 100644
index 0000000..6c3d5e5
--- /dev/null
+++ b/2_0_13/t/api/sendfile.t
@@ -0,0 +1,64 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catfile);
+
+my $url = '/TestAPI__sendfile';
+
+my $file = catfile Apache::Test::vars('serverroot'),
+ 'response/TestAPI/sendfile.pm';
+
+my $contents;
+open my $fh, $file or die "can't open $file: $!";
+# need binmode on Win32 so as not to strip \r, which
+# are included when sending with sendfile().
+binmode $fh;
+{ local $/; $contents = <$fh>; }
+close $fh;
+
+plan tests => 7, need 'HTML::HeadParser';
+
+{
+ my $header = "This is a header\n";
+ my $footer = "This is a footer\n";
+
+ my $received = GET_BODY "$url?withwrapper";
+ my $expected = join '', $header, $contents, $footer;
+ #t_debug($received);
+ ok $received && $received eq $expected;
+}
+
+{
+ my $received = GET_BODY "$url?offset";
+ my $expected = substr $contents, 3;
+ #t_debug($received);
+ ok $received && $received eq $expected;
+}
+
+{
+ my $received = GET_BODY "$url?len";
+ my $expected = substr $contents, 3, 50;
+ #t_debug($received);
+ ok $received && $received eq $expected;
+}
+
+{
+ # rc is checked and handled by the code
+ my $res = GET "$url?noexist.txt";
+ ok t_cmp($res->code, 500, "failed sendfile");
+ #t_debug($res->content);
+ ok $res->content =~ /an internal error/;
+}
+
+{
+ # rc is not checked in this one, testing the exception throwing
+ my $res = GET "$url?noexist-n-nocheck.txt";
+ ok t_cmp($res->code, 500, "failed sendfile");
+ #t_debug($res->content);
+ ok $res->content =~ /an internal error/;
+}
diff --git a/2_0_13/t/api/slurp_filename.t b/2_0_13/t/api/slurp_filename.t
new file mode 100644
index 0000000..b75da7e
--- /dev/null
+++ b/2_0_13/t/api/slurp_filename.t
@@ -0,0 +1,7 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+# we want r->filename to be "/slurp/slurp.pl", even though the
+# response handler is TestAPI::slurp_filename
+
+print GET_BODY_ASSERT "/slurp/slurp.pl";
diff --git a/2_0_13/t/api/status.t b/2_0_13/t/api/status.t
new file mode 100644
index 0000000..534da3b
--- /dev/null
+++ b/2_0_13/t/api/status.t
@@ -0,0 +1,44 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# testing $r->status/status_line
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 6;
+
+my $location = "/TestAPI__status";
+
+{
+ # test a valid HTTP/1.1 status code (303). In this test
+ # the handler returns OK, but sets a custom status. Apache will
+ # lookup the message "See Other" on its own
+ my $code = 303; # Apache2::Const::HTTP_SEE_OTHER
+ my $message = "See Other";
+ my $res = GET "$location?$code=";
+ ok t_cmp $res->code, $code, "code";
+ ok t_cmp $res->message, $message, "code message";
+ ok t_cmp $res->content, "", "content";
+}
+
+{
+ # test a non-existing HTTP/1.1 status code (499). In this test
+ # the handler returns OK, but sets a custom status_line.
+ # it also tries to set status (to a different value), but it
+ # should be ignored by Apache, since status_line is supposed to
+ # override status. the handler also sets a custom code message
+ # modules/http/http_filters.c r372958
+ # httpd 'zaps' the status_line if it doesn't match the status
+ # as of 2.2.1 (not released) so 2.2.2 (released)
+
+ my $code = 499; # not in HTTP/1.1
+ my $message = "FooBared";
+ my $res = GET "$location?$code=$message";
+ ok t_cmp $res->code, $code, "code";
+ ok t_cmp $res->message, $message, "code message";
+ ok t_cmp $res->content, "", "content";
+}
+
diff --git a/2_0_13/t/apr-ext/base64.t b/2_0_13/t/apr-ext/base64.t
new file mode 100644
index 0000000..0a6926c
--- /dev/null
+++ b/2_0_13/t/apr-ext/base64.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::base64;
+
+plan tests => TestAPRlib::base64::num_of_tests();
+
+TestAPRlib::base64::test();
diff --git a/2_0_13/t/apr-ext/brigade.t b/2_0_13/t/apr-ext/brigade.t
new file mode 100644
index 0000000..ce65cda
--- /dev/null
+++ b/2_0_13/t/apr-ext/brigade.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::brigade;
+
+plan tests => TestAPRlib::brigade::num_of_tests();
+
+TestAPRlib::brigade::test();
diff --git a/2_0_13/t/apr-ext/bucket.t b/2_0_13/t/apr-ext/bucket.t
new file mode 100644
index 0000000..5f7937f
--- /dev/null
+++ b/2_0_13/t/apr-ext/bucket.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::bucket;
+
+plan tests => TestAPRlib::bucket::num_of_tests();
+
+TestAPRlib::bucket::test();
diff --git a/2_0_13/t/apr-ext/date.t b/2_0_13/t/apr-ext/date.t
new file mode 100644
index 0000000..675d5c0
--- /dev/null
+++ b/2_0_13/t/apr-ext/date.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::date;
+
+plan tests => TestAPRlib::date::num_of_tests();
+
+TestAPRlib::date::test();
diff --git a/2_0_13/t/apr-ext/error.t b/2_0_13/t/apr-ext/error.t
new file mode 100644
index 0000000..297637a
--- /dev/null
+++ b/2_0_13/t/apr-ext/error.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::error;
+
+plan tests => TestAPRlib::error::num_of_tests();
+
+TestAPRlib::error::test();
diff --git a/2_0_13/t/apr-ext/finfo.t b/2_0_13/t/apr-ext/finfo.t
new file mode 100644
index 0000000..828edee
--- /dev/null
+++ b/2_0_13/t/apr-ext/finfo.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::finfo;
+
+plan tests => TestAPRlib::finfo::num_of_tests();
+
+TestAPRlib::finfo::test();
diff --git a/2_0_13/t/apr-ext/os.t b/2_0_13/t/apr-ext/os.t
new file mode 100644
index 0000000..bc3ca57
--- /dev/null
+++ b/2_0_13/t/apr-ext/os.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::os;
+
+plan tests => TestAPRlib::os::num_of_tests();
+
+TestAPRlib::os::test();
diff --git a/2_0_13/t/apr-ext/perlio.t b/2_0_13/t/apr-ext/perlio.t
new file mode 100644
index 0000000..543e57d
--- /dev/null
+++ b/2_0_13/t/apr-ext/perlio.t
@@ -0,0 +1,242 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+
+# XXX: this is pretty much the same test as
+# t/response/TestAPR/perlio.pm, but used outside mod_perl
+# consider avoiding the code duplication.
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache2::Build ();
+
+use Fcntl ();
+use File::Spec::Functions qw(catfile);
+
+#XXX: APR::LARGE_FILES_CONFLICT constant?
+#XXX: you can set to zero if largefile support is not enabled in Perl
+use constant LARGE_FILES_CONFLICT => 1;
+
+my $build = Apache2::Build->build_config;
+
+# XXX: only when apr-config is found APR will be linked against
+# libapr/libaprutil, probably need a more intuitive method for this
+# prerequisite
+# also need to check whether we build against the source tree, in
+# which case we APR.so won't be linked against libapr/libaprutil
+my $has_apr_config = $build->{apr_config_path} &&
+ !$build->httpd_is_source_tree;
+
+my $has_perlio_layers = 0;
+if ($has_apr_config) {
+ require APR;
+ require APR::PerlIO;
+ $has_perlio_layers = 1 if APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED();
+}
+
+my $tests = 12;
+my $lfs_tests = 3;
+
+$tests += $lfs_tests unless LARGE_FILES_CONFLICT;
+require APR; require APR::PerlIO;
+plan tests => $tests,
+ need {"this build couldn't find apr-config" => $has_apr_config,
+ "this build doesn't support PerlIO layers" => $has_perlio_layers,
+ };
+
+require APR::Pool;
+
+my $pool = APR::Pool->new();
+
+my $vars = Apache::Test::config()->{vars};
+my $dir = catfile $vars->{documentroot}, "perlio-ext";
+
+t_mkdir($dir);
+
+my $sep = "-- sep --\n";
+my @lines = ("This is a test: $$\n", "test line --sep two\n");
+
+my $expected = $lines[0];
+my $expected_all = join $sep, @lines;
+
+# write file
+my $file = catfile $dir, "test";
+t_debug "open file $file for writing";
+my $foo = "bar";
+open my $fh, ">:APR", $file, $pool
+ or die "Cannot open $file for writing: $!";
+ok ref($fh) eq 'GLOB';
+
+t_debug "write to a file:\n$expected\n";
+print $fh $expected_all;
+close $fh;
+
+# open() failure test
+{
+ # workaround for locale setups where the error message may be
+ # in a different language
+ open my $fh, "perlio_this_file_cannot_exist";
+ my $errno_string = "$!";
+
+ # non-existent file
+ my $file = "/this/file/does/not/exist";
+ if (open my $fh, "<:APR", $file, $pool) {
+ t_debug "must not be able to open $file!";
+ ok 0;
+ close $fh;
+ } else {
+ ok t_cmp("$!",
+ $errno_string,
+ "expected failure");
+ }
+}
+
+# seek/tell() tests
+unless (LARGE_FILES_CONFLICT) {
+ open my $fh, "<:APR", $file, $pool
+ or die "Cannot open $file for reading: $!";
+
+ # read the whole file so we can test the buffer flushed
+ # correctly on seek.
+ my $dummy = join '', <$fh>;
+
+ # Fcntl::SEEK_SET()
+ my $pos = 3; # rewinds after reading 6 chars above
+ seek $fh, $pos, Fcntl::SEEK_SET();
+ my $got = tell($fh);
+ ok t_cmp($got,
+ $pos,
+ "seek/tell the file Fcntl::SEEK_SET");
+
+ # Fcntl::SEEK_CUR()
+ my $step = 10;
+ $pos = tell($fh) + $step;
+ seek $fh, $step, Fcntl::SEEK_CUR();
+ $got = tell($fh);
+ ok t_cmp($got,
+ $pos,
+ "seek/tell the file Fcntl::SEEK_CUR");
+
+ # Fcntl::SEEK_END()
+ $pos = -s $file;
+ seek $fh, 0, Fcntl::SEEK_END();
+ $got = tell($fh);
+ ok t_cmp($got,
+ $pos,
+ "seek/tell the file Fcntl::SEEK_END");
+
+ close $fh;
+}
+
+# read() tests
+{
+ open my $fh, "<:APR", $file, $pool
+ or die "Cannot open $file for reading: $!";
+
+ # basic open test
+ ok ref($fh) eq 'GLOB';
+
+ # basic single line read
+ ok t_cmp(scalar(<$fh>),
+ $expected,
+ "single line read");
+
+ # slurp mode
+ seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start
+ local $/;
+ ok t_cmp(scalar(<$fh>),
+ $expected_all,
+ "slurp file");
+
+ # test ungetc (a long sep requires read ahead)
+ seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start
+ local $/ = $sep;
+ my @got_lines = <$fh>;
+ my @expect = ($lines[0] . $sep, $lines[1]);
+ ok t_cmp(\@got_lines,
+ \@expect,
+ "custom complex input record sep read");
+
+ close $fh;
+}
+
+
+# eof() tests
+{
+ open my $fh, "<:APR", $file, $pool
+ or die "Cannot open $file for reading: $!";
+
+ ok t_cmp(0,
+ int eof($fh), # returns false, not 0
+ "not end of file");
+ # go to the end and read so eof will return 1
+ seek $fh, 0, Fcntl::SEEK_END();
+ my $received = <$fh>;
+
+ t_debug($received);
+
+ ok t_cmp(eof($fh),
+ 1,
+ "end of file");
+ close $fh;
+}
+
+# dup() test
+{
+ open my $fh, "<:APR", $file, $pool
+ or die "Cannot open $file for reading: $!";
+
+ open my $dup_fh, "<&:APR", $fh
+ or die "Cannot dup $file for reading: $!";
+ close $fh;
+ ok ref($dup_fh) eq 'GLOB';
+
+ my $received = <$dup_fh>;
+
+ close $dup_fh;
+ ok t_cmp($received,
+ $expected,
+ "read/write a dupped file");
+}
+
+# unbuffered write
+{
+ open my $wfh, ">:APR", $file, $pool
+ or die "Cannot open $file for writing: $!";
+ open my $rfh, "<:APR", $file, $pool
+ or die "Cannot open $file for reading: $!";
+
+ my $expected = "This is an un buffering write test";
+ # unbuffer
+ my $oldfh = select($wfh); $| = 1; select($oldfh);
+ print $wfh $expected; # must be flushed to disk immediately
+
+ ok t_cmp(scalar(<$rfh>),
+ $expected,
+ "file unbuffered write");
+
+ # buffer up
+ $oldfh = select($wfh); $| = 0; select($oldfh);
+ print $wfh $expected; # should be buffered up and not flushed
+
+ ok t_cmp(scalar(<$rfh>),
+ undef,
+ "file buffered write");
+
+ close $wfh;
+ close $rfh;
+
+}
+
+
+# XXX: need tests
+# - for stdin/out/err as they are handled specially
+
+# XXX: tmpfile is missing:
+# consider to use 5.8's syntax:
+# open $fh, "+>", undef;
+
+# cleanup: t_mkdir will remove the whole tree including the file
+
diff --git a/2_0_13/t/apr-ext/pool.t b/2_0_13/t/apr-ext/pool.t
new file mode 100644
index 0000000..a2f9f15
--- /dev/null
+++ b/2_0_13/t/apr-ext/pool.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::pool;
+
+plan tests => TestAPRlib::pool::num_of_tests();
+
+TestAPRlib::pool::test();
diff --git a/2_0_13/t/apr-ext/status.t b/2_0_13/t/apr-ext/status.t
new file mode 100644
index 0000000..e5232cf
--- /dev/null
+++ b/2_0_13/t/apr-ext/status.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::status;
+
+plan tests => TestAPRlib::status::num_of_tests();
+
+TestAPRlib::status::test();
diff --git a/2_0_13/t/apr-ext/string.t b/2_0_13/t/apr-ext/string.t
new file mode 100644
index 0000000..ec2389f
--- /dev/null
+++ b/2_0_13/t/apr-ext/string.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::string;
+
+plan tests => TestAPRlib::string::num_of_tests();
+
+TestAPRlib::string::test();
diff --git a/2_0_13/t/apr-ext/table.t b/2_0_13/t/apr-ext/table.t
new file mode 100644
index 0000000..2e6f599
--- /dev/null
+++ b/2_0_13/t/apr-ext/table.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::table;
+
+plan tests => TestAPRlib::table::num_of_tests();
+
+TestAPRlib::table::test();
diff --git a/2_0_13/t/apr-ext/threadmutex.t b/2_0_13/t/apr-ext/threadmutex.t
new file mode 100644
index 0000000..64d9d02
--- /dev/null
+++ b/2_0_13/t/apr-ext/threadmutex.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::threadmutex;
+
+plan tests => TestAPRlib::threadmutex::num_of_tests(), need_threads;
+
+TestAPRlib::threadmutex::test();
diff --git a/2_0_13/t/apr-ext/threadrwlock.t b/2_0_13/t/apr-ext/threadrwlock.t
new file mode 100644
index 0000000..ba4a5db
--- /dev/null
+++ b/2_0_13/t/apr-ext/threadrwlock.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::threadrwlock;
+
+plan tests => TestAPRlib::threadrwlock::num_of_tests(), need_threads;
+
+TestAPRlib::threadrwlock::test();
diff --git a/2_0_13/t/apr-ext/uri.t b/2_0_13/t/apr-ext/uri.t
new file mode 100644
index 0000000..88d601d
--- /dev/null
+++ b/2_0_13/t/apr-ext/uri.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::uri;
+
+plan tests => TestAPRlib::uri::num_of_tests();
+
+TestAPRlib::uri::test();
diff --git a/2_0_13/t/apr-ext/util.t b/2_0_13/t/apr-ext/util.t
new file mode 100644
index 0000000..dd36331
--- /dev/null
+++ b/2_0_13/t/apr-ext/util.t
@@ -0,0 +1,12 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+use TestAPRlib::util;
+
+plan tests => TestAPRlib::util::num_of_tests();
+
+TestAPRlib::util::test();
diff --git a/2_0_13/t/apr-ext/uuid.t b/2_0_13/t/apr-ext/uuid.t
new file mode 100644
index 0000000..973bb65
--- /dev/null
+++ b/2_0_13/t/apr-ext/uuid.t
@@ -0,0 +1,31 @@
+#!perl -T
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache2::Build ();
+
+# XXX: only when apr-config is found APR will be linked against
+# libapr/libaprutil, probably need a more intuitive method for this
+# prerequisite
+# also need to check whether we build against the source tree, in
+# which case we APR.so won't be linked against libapr/libaprutil
+# In order to do this for all the apr-ext tests, could have
+# a wrapper around plan() that does a check like
+#######
+# my $build = Apache2::Build->build_config;
+#
+# my $has_apr_config = $build->{apr_config_path} &&
+# !$build->httpd_is_source_tree;
+# plan tests => TestAPRlib::uuid::num_of_tests(),
+# need {"the build couldn't find apr-config" => $has_apr_config};
+######
+# that is called from some TestAPRlib::common.
+
+use TestAPRlib::uuid;
+
+plan tests => TestAPRlib::uuid::num_of_tests();
+
+TestAPRlib::uuid::test();
diff --git a/2_0_13/t/apr/constants.t b/2_0_13/t/apr/constants.t
new file mode 100644
index 0000000..b9921e4
--- /dev/null
+++ b/2_0_13/t/apr/constants.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use ExtUtils::testlib;
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache::TestUtil;
+
+use APR::Const -compile => qw(:common POLLIN :filetype);
+use APR::Const qw(:hook);
+
+plan tests => 5;
+
+ok ! defined &POLLIN;
+ok t_cmp (APR::Const::SUCCESS, 0, 'APR::Const::SUCCESS');
+ok t_cmp (APR::Const::POLLIN, 0x001, 'APR::Const::POLLIN');
+ok t_cmp (HOOK_LAST, 20, 'HOOK_LAST');
+ok t_cmp (APR::Const::FILETYPE_UNKFILE, 127, 'APR::UNKFILE');
diff --git a/2_0_13/t/apr/pool_lifetime.t b/2_0_13/t/apr/pool_lifetime.t
new file mode 100644
index 0000000..4955c6f
--- /dev/null
+++ b/2_0_13/t/apr/pool_lifetime.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+Apache::TestRequest::user_agent(keep_alive => 1);
+
+plan tests => 2, need 'HTML::HeadParser';
+
+my $module = 'TestAPR::pool_lifetime';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+for (1..2) {
+ my $expected = "Pong";
+ my $received = GET $location;
+
+ ok t_cmp(
+ $received->content,
+ $expected,
+ "Pong",
+ );
+}
diff --git a/2_0_13/t/compat/conn_authen.t b/2_0_13/t/compat/conn_authen.t
new file mode 100644
index 0000000..880862f
--- /dev/null
+++ b/2_0_13/t/compat/conn_authen.t
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 1, need need_lwp, need_auth, 'HTML::HeadParser';
+
+my $location = "/TestCompat__conn_authen";
+
+ok GET_OK $location, username => 'dougm', password => 'foo';
+
diff --git a/2_0_13/t/compat/request_body.t b/2_0_13/t/compat/request_body.t
new file mode 100644
index 0000000..fc02b9b
--- /dev/null
+++ b/2_0_13/t/compat/request_body.t
@@ -0,0 +1,80 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 5;
+
+my $location = "/TestCompat__request_body";
+
+# $r->send_http_header('text/plain');
+{
+ my @data = (test => 'content-type');
+ ok t_cmp(
+ HEAD(query(@data))->content_type(),
+ "text/plain",
+ q{$r->send_http_header('text/plain')}
+ );
+}
+
+# $r->content
+{
+ my @data = (test => 'content');
+ my $content = join '=', @data;
+ ok t_cmp(
+ POST_BODY($location, content => $content),
+ "@data",
+ q{$r->content via POST}
+ );
+}
+
+# $r->Apache2::args
+{
+ my @data = (test => 'args');
+ ok t_cmp(
+ GET_BODY(query(@data)),
+ "@data",
+ q{$r->Apache2::args}
+ );
+}
+
+# encoding/decoding
+{
+ my %data = (
+ test => 'decoding',
+ body => '%DC%DC+%EC%2E+%D6%D6+%D6%2F',
+ );
+ ok t_cmp(
+ GET_BODY(query(%data)),
+ $data{body},
+ q{decoding}
+ );
+}
+
+
+# big POST
+{
+ my %data = (
+ test => 'big_input',
+ body => ('x' x 819_235),
+ );
+ my $content = join '=', %data;
+ ok t_cmp(
+ POST_BODY($location, content => $content),
+ length($data{body}),
+ q{big POST}
+ );
+}
+
+
+
+### helper subs ###
+sub query {
+ my (%args) = (@_ % 2) ? %{+shift} : @_;
+ "$location?" . join '&', map { "$_=$args{$_}" } keys %args;
+}
+
diff --git a/2_0_13/t/compat/send_fd.t b/2_0_13/t/compat/send_fd.t
new file mode 100644
index 0000000..a2e6d97
--- /dev/null
+++ b/2_0_13/t/compat/send_fd.t
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catfile);
+
+plan tests => 3, need 'HTML::HeadParser';
+
+my $config = Apache::Test::config();
+
+my $url = '/TestCompat__send_fd';
+
+my $data = GET_BODY($url);
+
+ok $data;
+
+my $module = catfile Apache::Test::vars('serverroot'),
+ 'response/TestCompat/send_fd.pm';
+
+ok length($data) == -s $module;
+
+$data = GET_BODY("$url?noexist.txt");
+
+ok $data =~ /Not Found/;
diff --git a/2_0_13/t/conf/extra.conf.in b/2_0_13/t/conf/extra.conf.in
new file mode 100644
index 0000000..67c2e23
--- /dev/null
+++ b/2_0_13/t/conf/extra.conf.in
@@ -0,0 +1,114 @@
+# needed to test $r->psignature
+ServerSignature On
+
+# The following tests require more than one interpreter during the
+# same request:
+#
+# perls Test
+# -----------
+# 2 t/modules/apache_status
+# 2 t/filter/both_str_req_proxy
+# 2 t/modules/proxy
+#
+# the following tests will clone a new perl interpreter via
+# ithreads.pm regardless of how many interpreters mod_perl has:
+#
+# t/perl/ithreads
+# t/perl/ithreads2
+#
+# therefore we need at most 2 interpreters, the missing one loading on
+# demand, but we start only with 1, so the startup is quick,
+# especially since we immediately restart. We also want MaxSpare to be
+# the same as Max, since we have more than one test that requires more
+# than one interpreter, so don't waste time to kill and start a new
+# one later -- keep it around once spawned
+#
+# Adjust PerlInterpMax and PerlInterpMaxSpare if the requirements change
+<IfDefine PERL_USEITHREADS>
+ PerlInterpStart 1
+ PerlInterpMax 2
+ PerlInterpMinSpare 1
+ PerlInterpMaxSpare 2
+</IfDefine>
+
+# make sure that we test under Taint and warnings mode enabled
+PerlSwitches -wT
+
+PerlChildExitHandler ModPerl::Test::exit_handler
+PerlModule TestExit::FromPerlModule
+
+#for t/modules/include.t
+<Directory @ServerRoot@/htdocs/includes>
+ <IfModule mod_mime.c>
+ AddOutputFilter INCLUDES .shtml
+ </IfModule>
+ # #virtual include of a script that sets content type is
+ # considered the same as #cmd by mod_include,
+ # therefore can't use IncludesNOEXEC here
+ Options Indexes FollowSymLinks Includes
+</Directory>
+
+<Directory @ServerRoot@/htdocs/includes-registry>
+ SetHandler perl-script
+ Options +ExecCGI +IncludesNoExec
+ PerlResponseHandler ModPerl::Registry
+ PerlOptions +ParseHeaders +GlobalRequest
+ <IfModule mod_mime.c>
+ AddOutputFilter INCLUDES .spl
+ </IfModule>
+</Directory>
+
+<IfModule mod_perl.c>
+ <IfDefine !MODPERL2>
+ # This should not be touched, since we're running with mod_perl 2
+ PerlModule Doesnt::Exist
+ </IfDefine>
+</IfModule>
+
+# <sandbox-friendly>
+# keep everything self-contained, to avoid problems with sandboxes
+# which break when things try to run off /tmp
+<IfModule mod_cgid.c>
+ ScriptSock logs/cgisock
+</IfModule>
+<IfModule mod_env.c>
+ SetEnv TMPDIR @t_logs@
+
+ # pass ld_library_path for non standard lib locations
+ # [rt.cpan.org #66085]
+ PassEnv LD_LIBRARY_PATH
+</IfModule>
+# </sandbox-friendly>
+
+<Location /status/perl>
+# PerlSetVar StatusOptionsAll On
+# PerlSetVar StatusDumper On
+# PerlSetVar StatusPeek On
+# PerlSetVar StatusLexInfo On
+# PerlSetVar StatusDeparse On
+# PerlSetVar StatusDeparseOptions "-p -sC"
+ PerlSetVar StatusTerse On
+# PerlSetVar StatusTerseSize On
+# PerlSetVar StatusTerseSizeMainSummary On
+ SetHandler modperl
+ PerlResponseHandler Apache2::Status
+</Location>
+
+# for TestApache::util
+PerlPassEnv LC_CTYPE
+PerlPassEnv LC_TIME
+
+# for TestCompat::apache_file
+PerlPassEnv TMPDIR
+PerlPassEnv TEMP
+
+# see t/filter/out_apache.t
+<VirtualHost filter_out_apache>
+ <IfModule mod_include.c>
+ # this filter is on purpose configured outside the Location
+ PerlSetOutputFilter INCLUDES
+ <Location />
+ Options +Includes
+ </Location>
+ </IfModule>
+</VirtualHost>
diff --git a/2_0_13/t/conf/extra.last.conf.in b/2_0_13/t/conf/extra.last.conf.in
new file mode 100644
index 0000000..c9e10ad
--- /dev/null
+++ b/2_0_13/t/conf/extra.last.conf.in
@@ -0,0 +1,139 @@
+PerlModule Apache2::Module
+
+PerlPostConfigRequire @ServerRoot@/conf/post_config_startup.pl
+
+### --------------------------------- ###
+<Perl >
+use Apache::Test ();
+if (Apache::Test::have_module('mod_alias.c')) {
+ push @Alias, ['/perl_sections', '@DocumentRoot@'];
+ $Location{'/perl_sections'} = {
+ 'PerlInitHandler' => 'ModPerl::Test::add_config',
+ 'AuthType' => 'Basic',
+ 'AuthName' => 'PerlSection',
+ 'PerlAuthenHandler' => 'TestHooks::authen_basic',
+ };
+}
+</Perl>
+
+<Perl >
+#Test tied %Location
+use TestCommon::TiePerlSection ();
+tie %Location, 'TestCommon::TiePerlSection';
+$Location{'/tied'} = 'test_tied';
+
+$Apache2::PerlSections::Save = 1;
+$Location{'/perl_sections_saved'} = {
+ 'AuthName' => 'PerlSection',
+ };
+#This is a comment
+$TestDirective::perl::comments="yes";
+$TestDirective::perl::PACKAGE = __PACKAGE__;
+</Perl>
+
+<Perl >
+$Apache2::PerlSections::Save = 1;
+$TestDirective::perl::filename = __FILE__;
+$TestDirective::perl::dollar_zero = $0;
+$TestDirective::perl::line = __LINE__;
+</Perl>
+
+#Handle re-entrant <Perl> sections
+<Perl >
+ use File::Spec;
+ my $file = File::Spec->catfile('@ServerRoot@', 'conf', 'perlsection.conf');
+ open my $fh, ">$file" or die "Can't open $file: $!";
+ print $fh join "\n", ('<Perl >', '$TestDirective::perl::Included++;', '</Perl>');
+ close $fh;
+ $Include = $file;
+</Perl>
+
+#Deprecated access to Apache2::ReadConfig:: still works
+<Perl >
+use Apache::Test ();
+if (Apache::Test::have_module('mod_alias.c')) {
+ push @Apache2::ReadConfig::Alias,
+ ['/perl_sections_readconfig', '@DocumentRoot@'];
+ $Apache2::ReadConfig::Location{'/perl_sections_readconfig'} = {
+ 'PerlInitHandler' => 'ModPerl::Test::add_config',
+ 'AuthType' => 'Basic',
+ 'AuthName' => 'PerlSection',
+ 'PerlAuthenHandler' => 'TestHooks::authen_basic',
+ };
+}
+</Perl>
+
+<Perl >
+$TestDirective::perl::base_server = Apache2::PerlSections->server;
+</Perl>
+
+<Perl >
+# make sure that these are set at the earliest possible time
+die '$ENV{MOD_PERL} not set!' unless $ENV{MOD_PERL};
+die '$ENV{MOD_PERL_API_VERSION} not set!'
+ unless $ENV{MOD_PERL_API_VERSION} == 2;
+</Perl>
+
+<VirtualHost perlsections>
+ <Perl >
+ $TestDirective::perl::vhost_server = Apache2::PerlSections->server;
+ </Perl>
+</VirtualHost>
+
+### --------------------------------- ###
+Perl $TestDirective::perl::worked="yes";
+
+### --------------------------------- ###
+=pod
+
+The following line is not seen by Apache
+
+PerlSetVar TestDirective__pod_hidden whatever
+
+=over apache
+
+PerlSetVar TestDirective__pod_over_worked yes
+
+=back
+
+This is some more pod
+
+=cut
+
+PerlSetVar TestDirective__pod_cut_worked yes
+
+#This used to trigger a segfault on startup
+#See http://thread.gmane.org/gmane.comp.apache.mod-perl/22750
+<IfDefine PERL_USEITHREADS>
+<VirtualHost inherit>
+ PerlSwitches +inherit
+ PerlOptions +Parent
+ Perl 1
+</VirtualHost>
+</IfDefine>
+
+#Single-line $PerlConfig
+<Perl>
+if (Apache::Test::have_module('mod_alias.c')) {
+ $PerlConfig = "Alias /perl_sections_perlconfig_scalar @DocumentRoot@";
+}
+</Perl>
+
+#Multi-line $PerlConfig
+<Perl>
+if (Apache::Test::have_module('mod_alias.c')) {
+ $PerlConfig = "Alias /perl_sections_perlconfig_scalar1 @DocumentRoot@
+ Alias /perl_sections_perlconfig_scalar2 @DocumentRoot@
+ ";
+}
+</Perl>
+
+#@PerlConfig
+<Perl>
+if (Apache::Test::have_module('mod_alias.c')) {
+ @PerlConfig = ("Alias /perl_sections_perlconfig_array1 @DocumentRoot@",
+ "Alias /perl_sections_perlconfig_array2 @DocumentRoot@",
+ );
+}
+</Perl>
+
diff --git a/2_0_13/t/conf/modperl_extra.pl b/2_0_13/t/conf/modperl_extra.pl
new file mode 100644
index 0000000..f80e416
--- /dev/null
+++ b/2_0_13/t/conf/modperl_extra.pl
@@ -0,0 +1,142 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+##########################################################
+### IMPORTANT: only things that must be run absolutely ###
+### during the config phase should be in this file ###
+##########################################################
+#
+# On the 2nd pass, during server-internal restart, none of the code
+# running from this file (config phase) will be able to log any STDERR
+# messages. This is because Apache redirects STDERR to /dev/null until
+# the open_logs phase. That means that any of the code fails, the
+# error message will be lost (but it should have failed on the 1st
+# pass, when STDERR goes to the console and any error messages are
+# properly logged). Therefore avoid putting any code here (unless
+# there is no other way) and instead put all the code to be run at the
+# server startup into post_config_startup.pl. when the latter is run,
+# STDERR is sent to $ErrorLog.
+#
+
+use strict;
+use warnings FATAL => 'all';
+
+die '$ENV{MOD_PERL} not set!' unless $ENV{MOD_PERL};
+die '$ENV{MOD_PERL_API_VERSION} not set!'
+ unless $ENV{MOD_PERL_API_VERSION} == 2;
+
+use File::Spec::Functions qw(canonpath catdir);
+
+use Apache2::ServerUtil ();
+use Apache2::ServerRec ();
+use Apache2::Process ();
+use Apache2::Log ();
+
+use Apache2::Const -compile => ':common';
+
+reorg_INC();
+
+startup_info();
+
+test_add_config();
+
+test_add_version_component();
+
+test_hooks_startup();
+
+test_modperl_env();
+
+
+
+### only subs below this line ###
+
+# need to run from config phase, since we want to adjust @INC as early
+# as possible
+sub reorg_INC {
+ # after Apache2 has pushed blib and core dirs including Apache2 on
+ # top reorg @INC to have first devel libs, then blib libs, and
+ # only then perl core libs
+ my $pool = Apache2::ServerUtil->server->process->pool;
+ my $project_root = canonpath
+ Apache2::ServerUtil::server_root_relative($pool, "..");
+ my (@a, @b, @c);
+ for (@INC) {
+ if (m|^\Q$project_root\E|) {
+ m|blib| ? push @b, $_ : push @a, $_;
+ }
+ else {
+ push @c, $_;
+ }
+ }
+ @INC = (@a, @b, @c);
+}
+
+# this can be run from post_config_startup.pl, but then it'll do the
+# logging twice, so in this case it's actually good to have this code
+# run during config phase, so it's logged only once (even though it's
+# run the second time, but STDERR == /dev/null)
+sub startup_info {
+ my $ap_mods = scalar grep { /^Apache2/ } keys %INC;
+ my $apr_mods = scalar grep { /^APR/ } keys %INC;
+
+ Apache2::Log->info("$ap_mods Apache2:: modules loaded");
+ Apache2::ServerRec->log->info("$apr_mods APR:: modules loaded");
+
+ my $server = Apache2::ServerUtil->server;
+ my $vhosts = 0;
+ for (my $s = $server->next; $s; $s = $s->next) {
+ $vhosts++;
+ }
+
+ $server->log->info("base server + $vhosts vhosts ready to run tests");
+}
+
+# need to run from config phase, since it changes server config
+sub test_add_config {
+ # testing $s->add_config()
+ my $conf = <<'EOC';
+# must use PerlModule here to check for segfaults
+PerlModule Apache::TestHandler
+<Location /apache/add_config>
+ SetHandler perl-script
+ PerlResponseHandler Apache::TestHandler::ok1
+</Location>
+EOC
+ Apache2::ServerUtil->server->add_config([split /\n/, $conf]);
+
+ # test a directive that triggers an early startup, so we get an
+ # attempt to use perl's mip early
+ Apache2::ServerUtil->server->add_config(['<Perl >', '1;', '</Perl>']);
+}
+
+# need to run from config phase, since it registers PerlPostConfigHandler
+sub test_add_version_component {
+ Apache2::ServerUtil->server->push_handlers(
+ PerlPostConfigHandler => \&add_my_version);
+
+ sub add_my_version {
+ my ($conf_pool, $log_pool, $temp_pool, $s) = @_;
+ $s->add_version_component("world domination series/2.0");
+ return Apache2::Const::OK;
+ }
+}
+
+# cleanup files for TestHooks::startup which can't be done from the
+# test itself because the files are created at the server startup and
+# the test needing these files may run more than once (t/SMOKE)
+#
+# we need to run it at config phase since we need to cleanup before
+# the open_logs phase
+sub test_hooks_startup {
+ require Apache::Test;
+ my $dir = catdir Apache::Test::vars('documentroot'), qw(hooks startup);
+ for (<$dir/*>) {
+ my $file = ($_ =~ /(.*(?:open_logs|post_config)-\d+)/);
+ unlink $file;
+ }
+}
+
+sub test_modperl_env {
+ # see t/response/TestModperl/env.pm
+ $ENV{MODPERL_EXTRA_PL} = __FILE__;
+}
+
+1;
diff --git a/2_0_13/t/conf/post_config_startup.pl b/2_0_13/t/conf/post_config_startup.pl
new file mode 100644
index 0000000..f8a09fb
--- /dev/null
+++ b/2_0_13/t/conf/post_config_startup.pl
@@ -0,0 +1,151 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+##########################################################
+### this file contains code that should be run on the ###
+### server startup but not during the config phase ###
+##########################################################
+use strict;
+use warnings FATAL => 'all';
+
+use Socket (); # test DynaLoader vs. XSLoader workaround for 5.6.x
+
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Process ();
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use Apache2::Connection ();
+use Apache2::Log ();
+
+use APR::Table ();
+use APR::Pool ();
+
+use ModPerl::Util (); #for CORE::GLOBAL::exit
+
+use Apache2::Const -compile => ':common';
+
+END {
+ warn "END in modperl_extra.pl, pid=$$\n";
+}
+
+test_apache_resource();
+
+test_apache_status();
+
+test_loglevel();
+
+test_perl_ithreads();
+
+test_server_shutdown_cleanup_register();
+
+test_method_obj();
+
+
+
+### only subs below this line ###
+
+sub test_apache_resource {
+ ### Apache2::Resource tests
+
+ # load first for the menu
+ require Apache2::Status;
+
+ # uncomment for local tests
+ #$ENV{PERL_RLIMIT_DEFAULTS} = 1;
+ #$Apache2::Resource::Debug = 1;
+
+ # requires optional BSD::Resource
+ return unless eval { require BSD::Resource };
+
+ require Apache2::Resource;
+}
+
+sub test_apache_status {
+ ### Apache2::Status tests
+ require Apache2::Status;
+ require Apache2::Module;
+ Apache2::Status->menu_item(
+ 'test_menu' => "Test Menu Entry",
+ sub {
+ my ($r) = @_;
+ return ["This is just a test entry"];
+ }
+ ) if Apache2::Module::loaded('Apache2::Status');
+}
+
+# test startup loglevel setting (under threaded mpms loglevel can be
+# changed only before threads are started) so here we test whether we
+# can still set it after restart
+sub test_loglevel {
+ use Apache2::Const -compile => 'LOG_INFO';
+ my $s = Apache2::ServerUtil->server;
+ my $oldloglevel = $s->loglevel(Apache2::Const::LOG_INFO);
+ # restore
+ $s->loglevel($oldloglevel);
+}
+
+sub test_perl_ithreads {
+ # this is needed for TestPerl::ithreads
+ # one should be able to boot ithreads at the server startup and
+ # then access the ithreads setup at run-time when a perl
+ # interpreter is running on a different native threads (testing
+ # that perl interpreters and ithreads aren't related to the native
+ # threads they are running on). This should work starting from
+ # perl-5.8.1 and higher.
+ use Config;
+ if ($] >= 5.008001 && $Config{useithreads}) {
+ eval { require threads; "threads"->import() };
+ }
+}
+
+sub test_server_shutdown_cleanup_register {
+ Apache2::ServerUtil::server_shutdown_cleanup_register sub {
+ warn <<'EOF';
+*** done with server_shutdown_cleanup_register ***
+********************************************************************************
+EOF
+ };
+
+ Apache2::ServerUtil::server_shutdown_cleanup_register sub {
+ die "testing server_shutdown_cleanup_register\n";
+ };
+
+ Apache2::ServerUtil::server_shutdown_cleanup_register sub {
+ warn <<'EOF';
+********************************************************************************
+*** This is a test for Apache2::ServerUtil::server_shutdown_cleanup_register ***
+*** Following a line consisting only of * characters there should be a line ***
+*** containing ***
+*** "cleanup died: testing server_shutdown_cleanup_register". ***
+*** The next line should then read ***
+*** "done with server_shutdown_cleanup_register" ***
+********************************************************************************
+EOF
+ };
+}
+
+sub ModPerl::Test::exit_handler {
+ my ($p, $s) = @_;
+
+ $s->log->info("Child process pid=$$ is exiting");
+
+ Apache2::Const::OK;
+
+}
+
+sub test_method_obj {
+ # see t/modperl/methodobj
+ require TestModperl::methodobj;
+ $TestModperl::MethodObj = TestModperl::methodobj->new;
+}
+
+sub ModPerl::Test::add_config {
+ my $r = shift;
+
+ #test adding config at request time
+ $r->add_config(['require valid-user']);
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/directive/perl.t b/2_0_13/t/directive/perl.t
new file mode 100644
index 0000000..1ffe3b2
--- /dev/null
+++ b/2_0_13/t/directive/perl.t
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 8, need need_auth, 'mod_alias.c', 'HTML::HeadParser';
+
+#so we don't have to require lwp
+my @auth = (Authorization => 'Basic ZG91Z206Zm9v'); #dougm:foo
+
+
+foreach my $location ("/perl_sections/index.html",
+ "/perl_sections_readconfig/index.html") {
+
+ sok {
+ ! GET_OK $location;
+ };
+
+ sok {
+ my $rc = GET_RC $location;
+ $rc == 401;
+ };
+
+ sok {
+ GET_OK $location, @auth;
+ };
+
+ sok {
+ ! GET_OK $location, $auth[0], $auth[1] . 'bogus';
+ };
+}
diff --git a/2_0_13/t/directive/perlcleanuphandler.t b/2_0_13/t/directive/perlcleanuphandler.t
new file mode 100644
index 0000000..47bbc1e
--- /dev/null
+++ b/2_0_13/t/directive/perlcleanuphandler.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest 'GET_BODY';
+
+plan tests => 3, need_lwp;
+
+my $module = 'TestDirective::perlcleanuphandler';
+
+Apache::TestRequest::user_agent(reset => 1, keep_alive=>1);
+sub u {Apache::TestRequest::module2url($module, {path=>$_[0]})}
+
+t_debug("connecting to ".u(''));
+ok t_cmp GET_BODY(u('/get?incr')), 'UNDEF', 'before increment';
+ok t_cmp GET_BODY(u('/get')), '1', 'incremented';
+(undef)=GET_BODY(u('/index.html?incr'));
+ok t_cmp GET_BODY(u('/get')), '2', 'incremented again';
diff --git a/2_0_13/t/directive/perlloadmodule2.t b/2_0_13/t/directive/perlloadmodule2.t
new file mode 100644
index 0000000..6533011
--- /dev/null
+++ b/2_0_13/t/directive/perlloadmodule2.t
@@ -0,0 +1,32 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $url = "/TestDirective__perlloadmodule2";
+
+plan tests => 3;
+
+{
+ my $location = "$url?srv";
+ my $expected = "srv: one two";
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "access server settings");
+}
+
+{
+ my $location = "$url?";
+ my $expected = "dir: one two three four";
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "server/dir merge");
+}
+
+{
+ my $location = "$url/subdir";
+ my $expected = "dir: one two three four five six";
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "server/dir/subdir merge");
+}
diff --git a/2_0_13/t/directive/perlloadmodule3.t b/2_0_13/t/directive/perlloadmodule3.t
new file mode 100644
index 0000000..8ced2a6
--- /dev/null
+++ b/2_0_13/t/directive/perlloadmodule3.t
@@ -0,0 +1,99 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = "TestDirective::perlloadmodule3";
+my $config = Apache::Test::config();
+my $base_hostport = Apache::TestRequest::hostport($config);
+my $path = Apache::TestRequest::module2path($module);
+
+# XXX: probably a good idea to split into more sub-tests, that test
+# smaller portions of information, but requires a more elaborate
+# logic. Alternatively could use diff($expected, $received).
+
+plan tests => 3;
+
+t_debug("connecting to $base_hostport");
+{
+ my $expected = <<EOI;
+Processing by main server.
+
+Section 1: Main Server
+MyAppend : MainServer
+MyList : ["MainServer"]
+MyOverride : MainServer
+MyPlus : 5
+
+Section 2: Location
+MyAppend : MainServer
+MyList : ["MainServer"]
+MyOverride : MainServer
+MyPlus : 5
+EOI
+ my $location = "http://$base_hostport/$path";
+ my $received = GET_BODY $location;
+ ok t_cmp($expected, $received, "server merge");
+}
+
+Apache::TestRequest::module($module);
+my $hostport = Apache::TestRequest::hostport($config);
+
+t_debug("connecting to $hostport");
+{
+ my $expected = <<EOI;
+Processing by virtual host.
+
+Section 1: Main Server
+MyAppend : MainServer
+MyList : ["MainServer"]
+MyOverride : MainServer
+MyPlus : 5
+
+Section 2: Virtual Host
+MyAppend : MainServer VHost
+MyList : ["MainServer", "VHost"]
+MyOverride : VHost
+MyPlus : 7
+
+Section 3: Location
+MyAppend : MainServer VHost Dir
+MyList : ["MainServer", "VHost", "Dir"]
+MyOverride : Dir
+MyPlus : 10
+EOI
+ my $location = "http://$hostport/$path";
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "server/dir merge");
+}
+
+{
+ my $expected = <<EOI;
+Processing by virtual host.
+
+Section 1: Main Server
+MyAppend : MainServer
+MyList : ["MainServer"]
+MyOverride : MainServer
+MyPlus : 5
+
+Section 2: Virtual Host
+MyAppend : MainServer VHost
+MyList : ["MainServer", "VHost"]
+MyOverride : VHost
+MyPlus : 7
+
+Section 3: Location
+MyAppend : MainServer VHost Dir SubDir
+MyList : ["MainServer", "VHost", "Dir", "SubDir"]
+MyOverride : SubDir
+MyPlus : 11
+EOI
+
+ my $location = "http://$hostport/$path/subdir";
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "server/dir/subdir merge");
+}
diff --git a/2_0_13/t/directive/perlloadmodule4.t b/2_0_13/t/directive/perlloadmodule4.t
new file mode 100644
index 0000000..8efff0f
--- /dev/null
+++ b/2_0_13/t/directive/perlloadmodule4.t
@@ -0,0 +1,14 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+use Apache::Test;
+
+my $module = "TestDirective::perlloadmodule4";
+my $config = Apache::Test::config();
+Apache::TestRequest::module($module);
+my $hostport = Apache::TestRequest::hostport($config);
+my $path = Apache::TestRequest::module2path($module);
+
+print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/directive/perlloadmodule5.t b/2_0_13/t/directive/perlloadmodule5.t
new file mode 100644
index 0000000..a466dee
--- /dev/null
+++ b/2_0_13/t/directive/perlloadmodule5.t
@@ -0,0 +1,14 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+use Apache::Test;
+
+my $module = "TestDirective::perlloadmodule5";
+my $config = Apache::Test::config();
+Apache::TestRequest::module($module);
+my $hostport = Apache::TestRequest::hostport($config);
+my $path = Apache::TestRequest::module2path($module);
+
+print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/directive/perlloadmodule6.t b/2_0_13/t/directive/perlloadmodule6.t
new file mode 100644
index 0000000..038d148
--- /dev/null
+++ b/2_0_13/t/directive/perlloadmodule6.t
@@ -0,0 +1,14 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+use Apache::Test;
+
+my $module = "TestDirective::perlloadmodule6";
+my $config = Apache::Test::config();
+Apache::TestRequest::module($module);
+my $hostport = Apache::TestRequest::hostport($config);
+my $path = Apache::TestRequest::module2path($module);
+
+print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/directive/perlmodule.t b/2_0_13/t/directive/perlmodule.t
new file mode 100644
index 0000000..e1b3b6f
--- /dev/null
+++ b/2_0_13/t/directive/perlmodule.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# this test tests PerlRequire configuration directive
+########################################################################
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = 'TestDirective::perlmodule';
+
+plan tests => 1;
+
+Apache::TestRequest::module($module);
+
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+my $path = Apache::TestRequest::module2path($module);
+t_debug("connecting to $hostport");
+
+ok t_cmp(GET_BODY("/$path"),
+ $module,
+ "testing PerlModule in $module");
+
diff --git a/2_0_13/t/directive/perlrequire.t b/2_0_13/t/directive/perlrequire.t
new file mode 100644
index 0000000..f2b48b5
--- /dev/null
+++ b/2_0_13/t/directive/perlrequire.t
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# this test tests PerlRequire configuration directive
+########################################################################
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $config = Apache::Test::config();
+my $path = Apache::TestRequest::module2path('TestDirective::perlrequire');
+
+my %checks = (
+ 'default' => 'PerlRequired by Parent',
+ 'TestDirective::perlrequire' => 'PerlRequired by VirtualHost',
+);
+
+delete $checks{'TestDirective::perlrequire'} unless have_perl 'ithreads';
+
+plan tests => scalar keys %checks;
+
+for my $module (sort keys %checks) {
+
+ Apache::TestRequest::module($module);
+ my $hostport = Apache::TestRequest::hostport($config);
+ t_debug("connecting to $hostport");
+
+ ok t_cmp(GET_BODY("http://$hostport/$path"),
+ $checks{$module},
+ "testing PerlRequire in $module");
+}
diff --git a/2_0_13/t/directive/setupenv.t b/2_0_13/t/directive/setupenv.t
new file mode 100644
index 0000000..1778be8
--- /dev/null
+++ b/2_0_13/t/directive/setupenv.t
@@ -0,0 +1,46 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 3;
+
+my $location = '/TestDirective__setupenv';
+
+my $env = GET_BODY $location;
+
+ok $env;
+
+my %env;
+
+for my $line (split /\n/, $env) {
+ next unless $line =~ /=/;
+ my ($key, $val) = split /=/, $line, 2;
+ $env{$key} = $val || '';
+}
+
+ok t_cmp $env{REQUEST_URI}, $location, "testing REQUEST_URI";
+
+{
+ # on Win32, some user environment variables, like HOME, may be
+ # passed through (via Apache?) if set, while system environment
+ # variables are not. so try to find an existing shell variable
+ # (that is not passed by Apache) and use it in the test to make
+ # sure mod_perl doesn't see it
+
+ my $var;
+ for (qw(SHELL USER OS)) {
+ $var = $_, last if exists $ENV{$_};
+ }
+
+ if (defined $var) {
+ ok t_cmp $env{$var}, undef, "env var $var=$ENV{$var} is ".
+ "set in shell, but shouldn't be seen inside mod_perl";
+ }
+ else {
+ skip "couldn't find a suitable env var to test against", 0;
+ }
+}
diff --git a/2_0_13/t/error/runtime.t b/2_0_13/t/error/runtime.t
new file mode 100644
index 0000000..dd961a5
--- /dev/null
+++ b/2_0_13/t/error/runtime.t
@@ -0,0 +1,38 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $location = "/TestError__runtime";
+
+my @untrapped = qw(plain_mp_error plain_non_mp_error
+ die_hook_confess_mp_error die_hook_confess_non_mp_error
+ die_hook_custom_mp_error die_hook_custom_non_mp_error);
+my @trapped = qw(eval_block_mp_error eval_block_non_mp_error
+ eval_string_mp_error eval_block_non_error
+ overload_test);
+
+plan tests => @untrapped + @trapped;
+
+for my $type (@untrapped) {
+ my $res = GET("$location?$type");
+ #t_debug($res->content);
+ ok t_cmp(
+ $res->code,
+ 500,
+ "500 error on $type exception",
+ );
+}
+
+for my $type (@trapped) {
+ my $body = GET_BODY("$location?$type");
+ ok t_cmp(
+ $body,
+ "ok $type",
+ "200 on $type exception",
+ );
+}
+
diff --git a/2_0_13/t/error/syntax.t b/2_0_13/t/error/syntax.t
new file mode 100644
index 0000000..81eaa04
--- /dev/null
+++ b/2_0_13/t/error/syntax.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = "/TestError__syntax";
+
+t_client_log_error_is_expected();
+my $res = GET($location);
+#t_debug($res->content);
+ok t_cmp(
+ $res->code,
+ 500,
+ "500 error on syntax error",
+ );
diff --git a/2_0_13/t/filter/TestFilter/both_str_con_add.pm b/2_0_13/t/filter/TestFilter/both_str_con_add.pm
new file mode 100644
index 0000000..d2bbbe5
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/both_str_con_add.pm
@@ -0,0 +1,92 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::both_str_con_add;
+
+# insert an input filter which lowers the case of the data
+# insert an output filter which adjusts s/modperl/mod_perl/
+
+# see also TestFilter::echo_filter
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Bucket ();
+use APR::Brigade ();
+use APR::Error ();
+use APR::Socket;
+
+use base qw(Apache2::Filter);
+
+use APR::Const -compile => qw(SUCCESS EOF SO_NONBLOCK);
+use Apache2::Const -compile => qw(OK MODE_GETLINE);
+
+sub pre_connection {
+ my Apache2::Connection $c = shift;
+
+ $c->add_input_filter(\&in_filter);
+ $c->add_output_filter(\&out_filter);
+
+ return Apache2::Const::OK;
+}
+
+sub in_filter : FilterConnectionHandler {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print(lc $buffer);
+ }
+
+ # test that $filter->ctx works here
+ $filter->ctx(1);
+
+ Apache2::Const::OK;
+}
+
+sub out_filter : FilterConnectionHandler {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $buffer =~ s/modperl/mod_perl/;
+ $filter->print($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my Apache2::Connection $c = shift;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
+
+ for (;;) {
+ $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE);
+ last if $bb->is_empty;
+
+ my $b = APR::Bucket::flush_create($c->bucket_alloc);
+ $bb->insert_tail($b);
+ $c->output_filters->pass_brigade($bb);
+ # fflush is the equivalent of the previous 3 lines of code:
+ # but it's tested elsewhere, here testing flush_create
+ # $c->output_filters->fflush($bb);
+ }
+
+ $bb->destroy;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+ <VirtualHost TestFilter::both_str_con_add>
+ PerlModule TestFilter::both_str_con_add
+ PerlPreConnectionHandler TestFilter::both_str_con_add::pre_connection
+ PerlProcessConnectionHandler TestFilter::both_str_con_add
+ </VirtualHost>
+</NoAutoConfig>
+
+
diff --git a/2_0_13/t/filter/TestFilter/both_str_native_remove.pm b/2_0_13/t/filter/TestFilter/both_str_native_remove.pm
new file mode 100644
index 0000000..8cb7a3a
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/both_str_native_remove.pm
@@ -0,0 +1,142 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::both_str_native_remove;
+
+# this tests verifies that we can remove input and output native
+# (non-mod_perl filters)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+use Apache2::FilterRec ();
+
+use APR::Table ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK DECLINED M_POST);
+
+# this filter removes the next filter in chain and itself
+sub remove_includes {
+ my $f = shift;
+
+ my $args = $f->r->args || '';
+ if ($args eq 'remove') {
+ my $ff = $f->next;
+ $ff->remove if $ff && $ff->frec->name eq 'includes';
+ }
+
+ $f->remove;
+
+ return Apache2::Const::DECLINED;
+}
+
+# this filter removes the next filter in chain and itself
+sub remove_deflate {
+ my $f = shift;
+
+ my $args = $f->r->args || '';
+ if ($args eq 'remove') {
+ for (my $ff = $f->r->input_filters; $ff; $ff = $ff->next) {
+ if ($ff->frec->name eq 'deflate') {
+ $ff->remove;
+ last;
+ }
+ }
+ }
+ $f->remove;
+
+ return Apache2::Const::DECLINED;
+}
+
+# this filter appends the output filter list at eos
+sub print_out_flist {
+ my $f = shift;
+
+ unless ($f->ctx) {
+ $f->ctx(1);
+ $f->r->headers_out->unset('Content-Length');
+ }
+
+ while ($f->read(my $buffer, 1024)) {
+ $f->print($buffer);
+ }
+
+ if ($f->seen_eos) {
+ my $flist = join ',', get_flist($f->r->output_filters);
+ $f->print("output2: $flist\n");
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub store_in_flist {
+ my $f = shift;
+ my $r = $f->r;
+
+ unless ($f->ctx) {
+ my $x = $r->pnotes('INPUT_FILTERS') || [];
+ push @$x, join ',', get_flist($f->r->input_filters);
+ $r->pnotes('INPUT_FILTERS' => $x);
+ }
+
+ return Apache2::Const::DECLINED;
+}
+
+
+sub response {
+ my $r = shift;
+
+ # just to make sure that print() won't flush, or we would get the
+ # count wrong
+ local $| = 0;
+
+ $r->content_type('text/plain');
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print("content: " . TestCommon::Utils::read_post($r) ."\n");
+ }
+
+ my $i=1;
+ for (@{ $r->pnotes('INPUT_FILTERS')||[] }) {
+ $r->print("input$i: $_\n");
+ $i++;
+ }
+
+ $r->subprocess_env(SSI_TEST => 'SSI OK');
+ $r->printf("output1: %s\n", join ',', get_flist($r->output_filters));
+
+ $r->rflush; # this sends the data in the buffer + flush bucket
+ $r->print('x<!--#echo var=');
+ $r->rflush; # this sends the data in the buffer + flush bucket
+ $r->print('"SSI_TEST" -->x'."\n");
+
+ Apache2::Const::OK;
+}
+
+sub get_flist {
+ my $f = shift;
+
+ my @flist = ();
+ for (; $f; $f = $f->next) {
+ push @flist, $f->frec->name;
+ }
+
+ return @flist;
+}
+
+1;
+__DATA__
+Options +Includes
+SetHandler modperl
+PerlModule TestFilter::both_str_native_remove
+PerlResponseHandler TestFilter::both_str_native_remove::response
+PerlOutputFilterHandler TestFilter::both_str_native_remove::remove_includes
+PerlSetOutputFilter INCLUDES
+PerlOutputFilterHandler TestFilter::both_str_native_remove::print_out_flist
+PerlInputFilterHandler TestFilter::both_str_native_remove::store_in_flist
+PerlInputFilterHandler TestFilter::both_str_native_remove::remove_deflate
+PerlSetInputFilter DEFLATE
+PerlInputFilterHandler TestFilter::both_str_native_remove::store_in_flist
diff --git a/2_0_13/t/filter/TestFilter/both_str_req_add.pm b/2_0_13/t/filter/TestFilter/both_str_req_add.pm
new file mode 100644
index 0000000..4f76426
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/both_str_req_add.pm
@@ -0,0 +1,89 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::both_str_req_add;
+
+# insert an input filter which lowers the case of the data
+# insert an output filter which strips spaces
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+sub header_parser {
+ my $r = shift;
+ # test adding by coderef
+ $r->add_input_filter(\&in_filter);
+ # test adding by sub's name
+ $r->add_output_filter("out_filter");
+
+ # test adding anon sub
+ $r->add_output_filter(sub {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $buffer .= "end";
+ $filter->print($buffer);
+ }
+
+ return Apache2::Const::OK;
+ });
+
+ return Apache2::Const::DECLINED;
+}
+
+sub in_filter {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print(lc $buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub out_filter {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $buffer =~ s/\s+//g;
+ $filter->print($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print(TestCommon::Utils::read_post($r));
+ }
+
+ return Apache2::Const::OK;
+}
+
+
+
+1;
+__DATA__
+<NoAutoConfig>
+ PerlModule TestFilter::both_str_req_add
+ <Location /TestFilter__both_str_req_add>
+ SetHandler modperl
+ PerlHeaderParserHandler TestFilter::both_str_req_add::header_parser
+ PerlResponseHandler TestFilter::both_str_req_add
+ </Location>
+</NoAutoConfig>
+
+
+
+
diff --git a/2_0_13/t/filter/TestFilter/both_str_req_mix.pm b/2_0_13/t/filter/TestFilter/both_str_req_mix.pm
new file mode 100644
index 0000000..0db61d8
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/both_str_req_mix.pm
@@ -0,0 +1,161 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::both_str_req_mix;
+
+# this is an elaborated test, where we mix several apache and mod_perl
+# filters, both input and output and verifying that they can work
+# together, preserving the order when the filters are of the same
+# priority
+
+# in this test the client, the client sends a compressed body,
+# 'DEFLATE' deflates it, then mod_perl filter 'transparent' filter
+# passes data through as-is. The following 'in_adjust' mod_perl filter
+# removes the string 'INPUT' from incoming data. The response handler
+# simply passes the data through. Next output filters get to work:
+# 'out_adjust_before_ssi' fixups the data to a valid SSI directive, by
+# removing the string 'OUTPUT' from the outgoing data, then the
+# 'INCLUDES' filter fetches the virtual file, and finally
+# 'out_adjust_after_ssi' fixes the file contents returned by SSI, by
+# removing the string 'REMOVE'
+#
+# Here is a visual representation of the transformations:
+#
+# => <network in>
+#
+# compressed data
+#
+# => DEFLATE
+#
+# <!--#include INPUTvirtual="/includes/OUTPUTclear.shtml" -->
+#
+# => transparent
+#
+# <!--#include INPUTvirtual="/includes/OUTPUTclear.shtml" -->
+#
+# => in_adjust
+#
+# <!--#include virtual="/includes/OUTPUTclear.shtml" -->
+#
+# <=> response handler
+#
+# <!--#include virtual="/includes/OUTPUTclear.shtml" -->
+#
+# <= out_adjust_before_ssi
+#
+# <!--#include virtual="/includes/clear.shtml" -->
+#
+# <= out_adjust_before_ssi
+#
+# <!--#include virtual="/includes/clear.shtml" -->
+#
+# <= INCLUDES
+#
+# This is a REMOVEclear text
+#
+# <= out_adjust_after_ssi
+#
+# This is a clear text
+#
+# <= DEFLATE
+#
+# compressed data
+#
+# <= <network out>
+
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use Apache::TestTrace;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant DEBUG => 1;
+
+sub transparent {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)){
+ debug "transparent buffer: $buffer";
+ $buffer =~ s/foo//;
+ $filter->print($buffer);
+ }
+
+ $filter->print("");
+
+ Apache2::Const::OK;
+}
+
+sub in_adjust { adjust("INPUT", @_)}
+sub out_adjust_before_ssi { adjust("OUTPUT", @_)}
+sub out_adjust_after_ssi { adjust("REMOVE", @_)}
+
+sub adjust {
+ my ($string, $filter) = @_;
+ my $sig = "adjust($string):";
+
+ while ($filter->read(my $buffer, 1024)){
+ debug "$sig before: $buffer";
+ $buffer =~ s/$string//;
+ debug "$sig after: $buffer";
+ $filter->print($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print(TestCommon::Utils::read_post($r));
+ }
+
+ return Apache2::Const::OK;
+}
+
+
+1;
+__DATA__
+<NoAutoConfig>
+ PerlModule TestFilter::both_str_req_mix
+ <Location /TestFilter__both_str_req_mix>
+ Options +Includes
+
+ # DEFLATE has a higher priority (AP_FTYPE_CONTENT_SET=20) than
+ # mod_perl request filters (AP_FTYPE_RESOURCE=10), so it's going
+ # to filter input first no matter how we insert other mod_perl
+ # filters. (mod_perl connection filter handlers have an even
+ # higher priority (AP_FTYPE_PROTOCOL = 30), see
+ # include/util_filter.h for those definitions).
+ #
+ # PerlSetInputFilter is only useful for preserving the
+ # insertion order of filters with the same priority
+ SetInputFilter DEFLATE
+ #PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
+ PerlInputFilterHandler TestFilter::both_str_req_mix::in_adjust
+ PerlInputFilterHandler TestFilter::both_str_req_mix::transparent
+
+ # here INCLUDES and adjust are both of the same priority
+ # (AP_FTYPE_RESOURCE), so PerlSetOutputFilter
+ PerlOutputFilterHandler TestFilter::both_str_req_mix::out_adjust_before_ssi
+ PerlSetOutputFilter INCLUDES
+ PerlOutputFilterHandler TestFilter::both_str_req_mix::out_adjust_after_ssi
+ #PerlOutputFilterHandler TestCommon::FilterDebug::snoop_request
+ PerlSetOutputFilter DEFLATE
+
+ SetHandler modperl
+ PerlResponseHandler TestFilter::both_str_req_mix
+ </Location>
+</NoAutoConfig>
+
+
+
+
diff --git a/2_0_13/t/filter/TestFilter/both_str_req_proxy.pm b/2_0_13/t/filter/TestFilter/both_str_req_proxy.pm
new file mode 100644
index 0000000..ed8ac0e
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/both_str_req_proxy.pm
@@ -0,0 +1,104 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::both_str_req_proxy;
+
+# very similar to TestFilter::both_str_req_add, but the request is
+# proxified. we filter the POSTed body before it goes via the proxy and
+# we filter the response after it returned from the proxy
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use Apache::TestTrace;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+sub in_filter {
+ my $filter = shift;
+
+ debug "input filter";
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print(lc $buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub out_filter {
+ my $filter = shift;
+
+ debug "output filter";
+
+ while ($filter->read(my $buffer, 1024)) {
+ $buffer =~ s/\s+//g;
+ $filter->print($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ debug "response handler";
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print(TestCommon::Utils::read_post($r));
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <IfModule mod_proxy.c>
+ <Proxy http://@servername@:@port@/*>
+ <IfModule mod_version.c>
+ <IfVersion < 2.3.0>
+ <IfModule @ACCESS_MODULE@>
+ Order Deny,Allow
+ Deny from all
+ Allow from @servername@
+ </IfModule>
+ </IfVersion>
+ <IfVersion > 2.4.1>
+ <IfModule mod_access_compat.c>
+ Order Deny,Allow
+ Deny from all
+ Allow from @servername@
+ </IfModule>
+ </IfVersion>
+ </IfModule>
+ </Proxy>
+
+ ProxyRequests Off
+
+ ProxyPass /TestFilter__both_str_req_proxy/ \
+ http://@servername@:@port@/TestFilter__both_str_req_proxy_content/
+ ProxyPassReverse /TestFilter__both_str_req_proxy/ \
+ http://@servername@:@port@/TestFilter__both_str_req_proxy_content/
+ </IfModule>
+
+ PerlModule TestFilter::both_str_req_proxy
+ <Location /TestFilter__both_str_req_proxy>
+ PerlInputFilterHandler TestFilter::both_str_req_proxy::in_filter
+ PerlOutputFilterHandler TestFilter::both_str_req_proxy::out_filter
+ </Location>
+ <Location /TestFilter__both_str_req_proxy_content>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::both_str_req_proxy
+ </Location>
+</NoAutoConfig>
+
+
+
+
diff --git a/2_0_13/t/filter/TestFilter/in_autoload.pm b/2_0_13/t/filter/TestFilter/in_autoload.pm
new file mode 100644
index 0000000..5595f44
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_autoload.pm
@@ -0,0 +1,41 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_autoload;
+
+# test that PerlInputFilterHandler autoloads the module containing the
+# handler (since it's ::handler and not a custom sub name we don't
+# have to explicitly call PerlModule)
+#
+# no point testing PerlOutputFilterHandler as it does the same
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Filter ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ debug "filter read: $buffer";
+ $filter->print(lc $buffer);
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+
+__DATA__
+<NoAutoConfig>
+ PerlModule TestCommon::Handlers
+ <Location /TestFilter__in_autoload>
+ SetHandler modperl
+ PerlResponseHandler TestCommon::Handlers::pass_through_response_handler
+ # no PerlModule TestFilter::in_load on purpose
+ PerlInputFilterHandler TestFilter::in_autoload
+ </Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_body.pm b/2_0_13/t/filter/TestFilter/in_bbs_body.pm
new file mode 100644
index 0000000..3380df1
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_bbs_body.pm
@@ -0,0 +1,60 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_bbs_body;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache2::Filter); #so we inherit MODIFY_CODE_ATTRIBUTES
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Brigade ();
+use APR::Bucket ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+use APR::Const -compile => ':common';
+
+sub handler : FilterRequestHandler {
+ my ($filter, $bb, $mode, $block, $readbytes) = @_;
+
+ $filter->next->get_brigade($bb, $mode, $block, $readbytes);
+
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+
+ last if $b->is_eos;
+
+ if ($b->read(my $data)) {
+ #warn"[$data]\n";
+ my $nb = APR::Bucket->new($bb->bucket_alloc, scalar reverse $data);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
+ }
+ }
+
+ Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ $r->puts($data);
+ }
+ else {
+ $r->puts("1..3\nok 1\n");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_bbs_body
+PerlResponseHandler TestFilter::in_bbs_body::response
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_consume.pm b/2_0_13/t/filter/TestFilter/in_bbs_consume.pm
new file mode 100644
index 0000000..b83f2f4
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_bbs_consume.pm
@@ -0,0 +1,107 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_bbs_consume;
+
+# this test consumes a chunk of input, then consumes and throws away
+# the rest of the data, finally returns to the caller that initial
+# chunk. This all happens during a single filter invocation. Even
+# though there about 6-7 incoming data brigades.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+use Apache2::Connection ();
+use APR::Brigade ();
+use APR::Bucket ();
+
+use Apache::TestTrace;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant READ_SIZE => 26;
+
+sub handler {
+ my ($filter, $bb, $mode, $block, $readbytes) = @_;
+ my $ba = $filter->r->connection->bucket_alloc;
+ my $seen_eos = 0;
+ my $satisfied = 0;
+ my $buffer = '';
+ debug_sub "filter called";
+
+ until ($satisfied) {
+ my $tbb = APR::Brigade->new($filter->r->pool, $ba);
+ $filter->next->get_brigade($tbb, $mode, $block, READ_SIZE);
+ debug "asking for a bb of " . READ_SIZE . " bytes\n";
+ my $data;
+ ($data, $seen_eos) = bb_data_n_eos($tbb);
+ $tbb->destroy;
+ $buffer .= $data;
+ length($buffer) < READ_SIZE ? redo : $satisfied++;
+ }
+
+ # consume all the remaining input
+ do {
+ my $tbb = APR::Brigade->new($filter->r->pool, $ba);
+ $filter->next->get_brigade($tbb, $mode, $block, $readbytes);
+ debug "discarding the next bb";
+ $seen_eos = bb_data_n_eos($tbb, 1); # only scan
+ $tbb->destroy;
+ } while (!$seen_eos);
+
+ if ($seen_eos) {
+ # flush the remainder
+ $bb->insert_tail(APR::Bucket->new($ba, $buffer));
+ $bb->insert_tail(APR::Bucket::eos_create($ba));
+ debug "seen eos, sending: " . length($buffer) . " bytes";
+ }
+ else {
+ die "Something is wrong, this filter should have been called only once";
+ }
+
+ return Apache2::Const::OK;
+}
+
+# if $scan_only is true, don't read the data, just look for eos
+sub bb_data_n_eos {
+ my ($bb, $scan_only) = @_;
+
+ if ($scan_only) {
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ return 1 if $b->is_eos;
+ }
+ return 0;
+ }
+
+ my $seen_eos = 0;
+
+ my @data;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ $seen_eos++, last if $b->is_eos;
+ $b->read(my $bdata);
+ push @data, $bdata;
+ }
+ return (join('', @data), $seen_eos);
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ #warn "HANDLER READ: $data\n";
+ $r->print($data);
+ }
+
+ return Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_bbs_consume
+PerlResponseHandler TestFilter::in_bbs_consume::response
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_inject_header.pm b/2_0_13/t/filter/TestFilter/in_bbs_inject_header.pm
new file mode 100644
index 0000000..5380c65
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_bbs_inject_header.pm
@@ -0,0 +1,260 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_bbs_inject_header;
+
+# this filter demonstrates two things:
+# 1. how to write a filter that will work only on HTTP headers
+# 2. how to inject extra HTTP headers
+#
+# the first task is simple for non-keepalive connections -- as soon as
+# a bucket which matches /^[\r\n]+$/ is read we can store that event
+# in the filter context and simply 'return Apache2::Const::DECLINED on the
+# future invocation, so not to slow things.
+#
+# it becomes much trickier with keepalive connection, since Apache
+# provides no API to tell you whether a new request is coming in. We
+# use $c->keepalives to figure out when a new request is coming in, by
+# comparing the previously stored keepalives count, which gets
+# incremented by Apache when the HTTP response headers are generated.
+#
+#
+# the second task is a bit trickier, as the headers_in core httpd
+# filter is picky and it wants each header to arrive in a separate
+# bucket, and moreover this bucket needs to be in its own brigade.
+# so this test arranges for this to happen.
+#
+# the test shows how to push headers at the end of all headers
+# and in the middle, whichever way you prefer.
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache2::Filter);
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Connection ();
+use APR::Brigade ();
+use APR::Bucket ();
+use APR::Table ();
+
+use Apache::TestTrace;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK DECLINED CONN_KEEPALIVE);
+use APR::Const -compile => ':common';
+
+my $header1_key = 'X-My-Protocol';
+my $header1_val = 'POST-IT';
+
+my %headers = (
+ 'X-Extra-Header2' => 'Value 2',
+ 'X-Extra-Header3' => 'Value 3',
+);
+
+my $request_body = "This body shouldn't be seen by the filter";
+
+# returns 1 if a bucket with a header was inserted to the $bb's tail,
+# otherwise returns 0 (i.e. if there are no buckets to insert)
+sub inject_header_bucket {
+ my ($bb, $ctx) = @_;
+
+ return 0 unless @{ $ctx->{buckets} };
+
+ my $b = shift @{ $ctx->{buckets} };
+ $bb->insert_tail($b);
+
+ if (1) {
+ # extra debug, wasting cycles
+ $b->read(my $data);
+ debug "injected header: [$data]";
+ }
+ else {
+ debug "injected header";
+ }
+
+ # next filter invocations will bring the request body if any
+ if ($ctx->{seen_body_separator} && !@{ $ctx->{buckets} }) {
+ $ctx->{done_with_headers} = 1;
+ $ctx->{seen_body_separator} = 0;
+ }
+
+ return 1;
+}
+
+sub context {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+ my $c = $filter->c;
+ unless ($ctx) {
+ debug "filter context init";
+ $ctx = {
+ buckets => [],
+ done_with_headers => 0,
+ seen_body_separator => 0,
+ keepalives => $c->keepalives,
+ };
+
+ # since we are going to manipulate the reference stored in
+ # ctx, it's enough to store it only once, we will get the same
+ # reference in the following invocations of that filter
+ $filter->ctx($ctx);
+ return $ctx;
+ }
+
+ if ($c->keepalive == Apache2::Const::CONN_KEEPALIVE &&
+ $ctx->{done_with_headers} &&
+ $c->keepalives > $ctx->{keepalives}) {
+
+ debug "a new request resetting the input filter state";
+
+ $ctx->{buckets} = [];
+ $ctx->{done_with_headers} = 0;
+ $ctx->{seen_body_separator} = 0;
+ $ctx->{keepalives} = $c->keepalives;
+ }
+
+ return $ctx;
+
+}
+
+sub handler : FilterConnectionHandler {
+ my ($filter, $bb, $mode, $block, $readbytes) = @_;
+
+ debug join '', "-" x 20 , " input filter called -", "-" x 20;
+
+ my $ctx = context($filter);
+ my $c = $filter->c;
+
+ # reset the filter state, we start a new request
+ if ($c->keepalive == Apache2::Const::CONN_KEEPALIVE &&
+ $ctx->{done_with_headers} && $c->notes->get('reset_request')) {
+ debug "a new request resetting the input filter state";
+ $c->notes->set('reset_request' => 0);
+ $ctx->{buckets} = [];
+ $ctx->{seen_body_separator} = 0;
+ $ctx->{done_with_headers} = 0;
+ }
+
+ # handling the HTTP request body
+ if ($ctx->{done_with_headers}) {
+ # XXX: when the bug in httpd filter will be fixed all the
+ # code in this branch will be replaced with:
+ # $filter->remove;
+ # return Apache2::Const::DECLINED;
+ # at the moment (2.0.48) it doesn't work
+ # so meanwhile tell the mod_perl filter core to pass-through
+ # the brigade unmodified
+ debug "passing the body through unmodified";
+ return Apache2::Const::DECLINED;
+ }
+
+ # any custom HTTP header buckets to inject?
+ return Apache2::Const::OK if inject_header_bucket($bb, $ctx);
+
+ # normal HTTP headers processing
+ my $ctx_bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
+ my $rv = $filter->next->get_brigade($ctx_bb, $mode, $block, $readbytes);
+ return $rv unless $rv == APR::Const::SUCCESS;
+
+ while (!$ctx_bb->is_empty) {
+ my $b = $ctx_bb->first;
+
+ if ($b->is_eos) {
+ debug "EOS!!!";
+ $b->remove;
+ $bb->insert_tail($b);
+ last;
+ }
+
+ $b->read(my $data);
+ # remove must happen after read, since it may cause split and
+ # some new buckets inserted behind - if remove called too
+ # early, those buckets will be lost
+ $b->remove;
+ debug "filter read:\n[$data]";
+
+ # check that we really work only on the headers
+ die "This filter should not ever receive the request body, " .
+ "but HTTP headers" if ($data||'') eq $request_body;
+
+ if ($data and $data =~ /^POST/) {
+ # demonstrate how to add a header while processing other headers
+ my $header = "$header1_key: $header1_val\r\n";
+ push @{ $ctx->{buckets} }, APR::Bucket->new($c->bucket_alloc, $header);
+ debug "queued header [$header]";
+ }
+ elsif ($data =~ /^[\r\n]+$/) {
+ # normally the body will start coming in the next call to
+ # get_brigade, so if your filter only wants to work with
+ # the headers, it can decline all other invocations if that
+ # flag is set. However since in this test we need to send
+ # a few extra bucket brigades, we will turn another flag
+ # 'done_with_headers' when 'seen_body_separator' is on and
+ # all headers were sent out
+ debug "END of original HTTP Headers";
+ $ctx->{seen_body_separator}++;
+
+ # we hit the headers and body separator, which is a good
+ # time to add extra headers:
+ for my $key (keys %headers) {
+ my $header = "$key: $headers{$key}\r\n";
+ push @{ $ctx->{buckets} }, APR::Bucket->new($c->bucket_alloc, $header);
+ debug "queued header [$header]";
+ }
+
+ # but at the same time we must ensure that the
+ # the separator header will be sent as a last header
+ # so we send one newly added header and push the separator
+ # to the end of the queue
+ # XXX: this is broken: the bucket must be set-aside before
+ # it can be stashed away (missing $b->setaside wrapper)
+ push @{ $ctx->{buckets} }, $b;
+ debug "queued header [$data]";
+ inject_header_bucket($bb, $ctx);
+ next; # inject_header_bucket already called insert_tail
+ # notice that if we didn't inject any headers, this will
+ # still work ok, as inject_header_bucket will send the
+ # separator header which we just pushed to its queue
+ }
+ else {
+ # fall through
+ }
+
+ $bb->insert_tail($b);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ # propogate the input headers and the input back to the client
+ # as we need to do the validations on the client side
+ $r->headers_out->set($header1_key =>
+ $r->headers_in->get($header1_key)||'');
+
+ for my $key (sort keys %headers) {
+ $r->headers_out->set($key => $r->headers_in->get($key)||'');
+ }
+
+ my $data = TestCommon::Utils::read_post($r);
+ $r->print($data);
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestFilter::in_bbs_inject_header>
+ PerlModule TestFilter::in_bbs_inject_header
+ PerlInputFilterHandler TestFilter::in_bbs_inject_header
+ <Location /TestFilter__in_bbs_inject_header>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::in_bbs_inject_header::response
+ </Location>
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_msg.pm b/2_0_13/t/filter/TestFilter/in_bbs_msg.pm
new file mode 100644
index 0000000..12e0868
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_bbs_msg.pm
@@ -0,0 +1,75 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_bbs_msg;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache2::Filter);
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Brigade ();
+use APR::Bucket ();
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => ':common';
+
+use Apache::TestTrace;
+
+my $from_url = '/input_filter.html';
+my $to_url = '/TestFilter__in_bbs_msg';
+
+sub handler : FilterConnectionHandler {
+ my ($filter, $bb, $mode, $block, $readbytes) = @_;
+
+ debug "FILTER CALLED";
+
+ $filter->next->get_brigade($bb, $mode, $block, $readbytes);
+
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+
+ last if $b->is_eos;
+
+ if ($b->read(my $data)) {
+ next unless $data =~ s|GET $from_url|GET $to_url|;
+ debug "GET line rewritten to be:\n$data";
+ my $nb = APR::Bucket->new($bb->bucket_alloc, $data);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
+ }
+
+ # XXX: currently a bug in httpd doesn't allow to remove
+ # the first connection filter. once it's fixed adjust the test
+ # to test that it was invoked only once.
+ # debug "removing the filter";
+ # $filter->remove; # this filter is no longer needed
+ }
+
+ Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ $r->puts("1..1\nok 1\n");
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestFilter::in_bbs_msg>
+ PerlModule TestFilter::in_bbs_msg
+ PerlInputFilterHandler TestFilter::in_bbs_msg
+
+ <Location /TestFilter__in_bbs_msg>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::in_bbs_msg::response
+ </Location>
+
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_underrun.pm b/2_0_13/t/filter/TestFilter/in_bbs_underrun.pm
new file mode 100644
index 0000000..f8f33bb
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_bbs_underrun.pm
@@ -0,0 +1,154 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_bbs_underrun;
+
+# this test exercises the underrun filter concept. Sometimes filters
+# need to read at least N bytes before they can apply their
+# transformation. It's quite possible that reading one bucket brigade
+# is not enough. But two or more are needed.
+#
+# When the filter realizes that it doesn't have enough data, it can
+# stash the read data in the context, and wait for the next
+# invocation, meanwhile it must return an empty bb to the filter that
+# has called it. This is not efficient. Instead of returning an empty
+# bb to a caller, the input filter can initiate the retrieval of extra
+# bucket brigades, after one was received. Notice that this is
+# absolutely transparent to any filters before or after the current
+# filter.
+#
+# to see the filter at work, run it as:
+# t/TEST -trace=debug -v filter/in_bbs_underrun
+#
+# and look in the error_log. You will see something like:
+#
+# ==> TestFilter::in_bbs_underrun::handler : filter called
+# ==> asking for a bb
+# ==> asking for a bb
+# ==> asking for a bb
+# ==> storing the remainder: 7611 bytes
+# ==> TestFilter::in_bbs_underrun::handler : filter called
+# ==> asking for a bb
+# ==> asking for a bb
+# ==> storing the remainder: 7222 bytes
+# ==> TestFilter::in_bbs_underrun::handler : filter called
+# ==> asking for a bb
+# ==> seen eos, flushing the remaining: 8182 bytes
+#
+# it's clear from the log that the filter was invoked 3 times, however
+# it has consumed 6 bucket brigades
+#
+# finally, we have to note that this is impossible to do with
+# streaming filters, since they can only read data from one bucket
+# brigade. So you must process bucket brigades.
+#
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use Apache::TestTrace;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant SIZE => 1024*16 + 5; # ~16k
+
+sub handler {
+ my ($filter, $bb, $mode, $block, $readbytes) = @_;
+ my $ba = $filter->r->connection->bucket_alloc;
+ my $ctx = $filter->ctx;
+ my $buffer = defined $ctx ? $ctx : '';
+ $ctx = ''; # reset
+ my $seen_eos = 0;
+ my $data;
+ debug_sub "filter called";
+
+ # fetch and consume bucket brigades untill we have at least SIZE
+ # bytes to work with
+ do {
+ my $tbb = APR::Brigade->new($filter->r->pool, $ba);
+ $filter->next->get_brigade($tbb, $mode, $block, $readbytes);
+ debug "asking for a bb";
+ ($data, $seen_eos) = flatten_bb($tbb);
+ $tbb->destroy;
+ $buffer .= $data;
+ } while (!$seen_eos && length($buffer) < SIZE);
+
+ # now create a bucket per chunk of SIZE size and put the remainder
+ # in ctx
+ for (split_buffer($buffer)) {
+ if (length($_) == SIZE) {
+ $bb->insert_tail(APR::Bucket->new($bb->bucket_alloc, $_));
+ }
+ else {
+ $ctx .= $_;
+ }
+ }
+
+ if ($seen_eos) {
+ # flush the remainder
+ $bb->insert_tail(APR::Bucket->new($bb->bucket_alloc, $ctx));
+ $bb->insert_tail(APR::Bucket::eos_create($ba));
+ debug "seen eos, flushing the remaining: " . length($ctx) . " bytes";
+ }
+ else {
+ # will re-use the remainder on the next invocation
+ $filter->ctx($ctx);
+ debug "storing the remainder: " . length($ctx) . " bytes";
+ }
+
+ return Apache2::Const::OK;
+}
+
+# split in words of SIZE chars and a remainder
+sub split_buffer {
+ my $buffer = shift;
+ if ($] < 5.007) {
+ my @words = $buffer =~ /(.{@{[SIZE]}}|.+)/g;
+ return @words;
+ }
+ else {
+ # available only since 5.7.x+
+ return unpack "(A" . SIZE . ")*", $buffer;
+ }
+}
+
+sub flatten_bb {
+ my ($bb) = shift;
+
+ my $seen_eos = 0;
+
+ my @data;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ $seen_eos++, last if $b->is_eos;
+ $b->read(my $bdata);
+ push @data, $bdata;
+ }
+ return (join('', @data), $seen_eos);
+}
+
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ #warn "HANDLER READ: $data\n";
+ my $length = length $data;
+ $r->print("read $length chars");
+ }
+
+ return Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_bbs_underrun
+PerlResponseHandler TestFilter::in_bbs_underrun::response
+PerlInputFilterHandler TestFilter::in_bbs_underrun::handler
+#PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
diff --git a/2_0_13/t/filter/TestFilter/in_error.pm b/2_0_13/t/filter/TestFilter/in_error.pm
new file mode 100644
index 0000000..633b3a3
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_error.pm
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_error;
+
+# errors in filters should be properly propogated to httpd
+
+# XXX: need to test output as well, and separately connection and
+# request filters
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+use APR::Table ();
+
+use Apache::TestTrace;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $filter = shift;
+
+ debug join '', "-" x 20 , " filter called ", "-" x 20;
+
+ die "This filter must die";
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ # cause taint problems, as there was a bug (panic: POPSTACK)
+ # caused when APR/Error.pm was attempted to be loaded from
+ # $r->read() when the latter was trying to croak about the failed
+ # read, due to the filter returning 500
+ eval { system('echo', 'hello') };
+
+ t_server_log_error_is_expected(2);
+ my $len = $r->read(my $data, $r->headers_in->{'Content-Length'});
+
+ $r->content_type('text/plain');
+ $r->print("it shouldn't be printed, because the input filter has died");
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_error
+PerlResponseHandler TestFilter::in_error::response
diff --git a/2_0_13/t/filter/TestFilter/in_init_basic.pm b/2_0_13/t/filter/TestFilter/in_init_basic.pm
new file mode 100644
index 0000000..630a511
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_init_basic.pm
@@ -0,0 +1,81 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_init_basic;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use base qw(Apache2::Filter);
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant READ_SIZE => 1024;
+
+# this filter is expected to be called once
+# it'll set a note, with the count
+sub transparent_init : FilterInitHandler {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+ $ctx->{init}++;
+ $filter->r->notes->set(init => $ctx->{init});
+ $filter->ctx($ctx);
+
+ return Apache2::Const::OK;
+}
+
+# this filter passes the data through unmodified and sets a note
+# counting how many times it was invoked
+sub transparent : FilterRequestHandler
+ FilterHasInitHandler(\&transparent_init)
+ {
+ my ($filter, $bb, $mode, $block, $readbytes) = @_;
+
+ my $ctx = $filter->ctx;
+ $ctx->{run}++;
+ $filter->r->notes->set(run => $ctx->{run});
+ $filter->ctx($ctx);
+
+ $filter->next->get_brigade($bb, $mode, $block, $readbytes);
+
+ return Apache2::Const::OK;
+}
+
+
+
+# this filter is not supposed to get a chance to run, since its init
+# handler immediately removes it
+sub suicide_init : FilterInitHandler { shift->remove(); Apache2::Const::OK }
+sub suicide : FilterHasInitHandler(\&suicide_init) {
+ die "this filter is not supposed to have a chance to run";
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print(TestCommon::Utils::read_post($r));
+ }
+
+ my @keys = qw(init run);
+ my %times = map { $_ => $r->notes->get($_)||0 } @keys;
+ $r->print("$_ $times{$_}\n") for @keys;
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_init_basic
+PerlResponseHandler TestFilter::in_init_basic::response
+PerlInputFilterHandler TestFilter::in_init_basic::suicide
+PerlInputFilterHandler TestFilter::in_init_basic::transparent
diff --git a/2_0_13/t/filter/TestFilter/in_str_bin_data.pm b/2_0_13/t/filter/TestFilter/in_str_bin_data.pm
new file mode 100644
index 0000000..f304f43
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_bin_data.pm
@@ -0,0 +1,58 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_bin_data;
+
+# test that $r->print and $f->print handle binary data correctly
+# (e.g. doesn't truncate on "\0" if there is more data after it)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+use Apache2::Filter ();
+
+use Apache::TestTrace;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+sub pass_through {
+ my $f = shift;
+
+ while ($f->read(my $buffer, 1024)) {
+ debug "read: " . length ($buffer) . "b [$buffer]";
+ $f->print($buffer);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ my $length = length $data;
+ debug "pass through $length bytes of $data\n";
+ $r->print($data);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+PerlModule TestFilter::in_str_bin_data
+<Location /TestFilter__in_str_bin_data_filter>
+ PerlInputFilterHandler TestFilter::in_str_bin_data::pass_through
+ SetHandler modperl
+ PerlResponseHandler TestFilter::in_str_bin_data
+</Location>
+<Location /TestFilter__in_str_bin_data>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::in_str_bin_data
+</Location>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/filter/TestFilter/in_str_consume.pm b/2_0_13/t/filter/TestFilter/in_str_consume.pm
new file mode 100644
index 0000000..4bd32ce
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_consume.pm
@@ -0,0 +1,149 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_consume;
+
+# this test verifies that streaming filters framework handles
+# gracefully the case when a filter doesn't print anything at all to
+# the caller.
+
+# the real problem is that in the streaming filters we can't consume
+# more than one bucket brigade during a single filter invocation,
+# which we can in non-stream filters., (e.g. see in_bbs_underrun.pm)
+#
+# it seems that this works just fine (2.0.46+) and older httpds
+# had problems when a filter invocation hasn't printed a thing.
+#
+# currently if the streaming filter doesn't print anything, the
+# upstream filter gets an empty brigade brigade (easily verified with
+# the snooping debug filter). Of course if the filter returns
+# Apache2::Const::DECLINED the unconsumed data will be passed to upstream filter
+#
+# However this filter has a problem. Since it doesn't consume all the
+# data, the client is left with un-read data, and when the response is
+# sent a client get the broken pipe on the socket. It seems that LWP
+# on linux handles that situation gracefully, but not on win32, where
+# it silently dies. Other clients may have similar problems as
+# well. The proper solution is to consume all the data till EOS and
+# just drop it on the floor if it's unneeded. Unfortunately we waste
+# the resources of passing the data through all filters in the chain
+# and doing a wasteful work, but currently there is no way to tell the
+# in_core network filter to discard all the data without passing it
+# upstream. Notice that in this test we solve the problem in a
+# different manner, we simply call $r->discard_request_body which does
+# the trick. However it's inappropriate for a stand-alone filter, who
+# should read all the data in instead.
+#
+# this test receives about 10 bbs
+# it reads only the first 23 bytes of each bb and discards the rest
+# since it wants only 105 bytes it partially consumes only the first 5 bbs
+# since it doesn't read all the data in, it'll never see EOS
+# therefore once it has read all 105 bytes, it manually sets the EOS flag
+# and the rest of the bbs are ignored, the filter is invoked only 5 times
+#
+# to debug this filter run it as:
+#
+# t/TEST -v -trace=debug filter/in_str_consume
+#
+# to enable upstream and downstream filter snooping, uncomment the
+# snooping filters directives at the end of this file and rerun:
+# t/TEST -conf
+#
+# to see what happens inside the filter, assuming that you built
+# mod_perl with MP_TRACE=1, run:
+# env MOD_PERL_TRACE=f t/TEST -v -trace=debug filter/in_str_consume
+#
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Filter ();
+use Apache::TestTrace;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant READ_BYTES_TOTAL => 105;
+use constant READ_BYTES_FIRST => 23;
+
+sub handler {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx || { data => '', count => '1'};
+ debug "FILTER INVOKED: $ctx->{count}";
+
+ # read untill READ_BYTES read, no matter how many filter
+ # invocations it'll take
+ my $wanted_total = READ_BYTES_TOTAL - length $ctx->{data};
+ my $wanted_current = READ_BYTES_FIRST;
+ my $wanted = $wanted_total;
+ $wanted = $wanted_current if $wanted > $wanted_current;
+ debug "total wanted: $wanted_total bytes";
+ debug "this bb wanted: $wanted bytes";
+ while ($wanted) {
+ my $len = $filter->read(my $buffer, $wanted);
+ $ctx->{data} .= $buffer;
+ $wanted_total -= $len;
+ $wanted -= $len;
+ debug "FILTER READ: [$buffer]";
+ debug "FILTER READ: $len ($wanted_total more to go)";
+ last unless $len; # no more data to read in this bb
+ }
+
+ $ctx->{count}++;
+
+ unless ($wanted_total) {
+ # we don't want to read the rest if there is anything left
+ $filter->seen_eos(1);
+ # but we really should, though we workaround it in the
+ # response handler, by calling $r->discard_request_body
+ }
+
+ if ($filter->seen_eos) {
+ # flush the data if we are done
+ $filter->print($ctx->{data});
+ }
+ else {
+ # store the data away
+ $filter->ctx($ctx);
+
+ # notice that it seems to work even though we don't print
+ # anything. the upstream filter gets an empty bb.
+
+ # alternatively could print the chunks of data that we read,
+ # if we don't need to have it as a whole chunk
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+
+ # tell Apache to get rid of the rest of the request body
+ # if we don't a client will get a broken pipe and may fail to
+ # handle this situation gracefully
+ $r->discard_request_body;
+
+ my $len = length $data;
+ debug "HANDLER READ: $len bytes\n";
+ $r->print($len);
+ }
+
+ return Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_str_consume
+PerlResponseHandler TestFilter::in_str_consume::response
+#PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
+PerlInputFilterHandler TestFilter::in_str_consume::handler
+#PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
diff --git a/2_0_13/t/filter/TestFilter/in_str_declined.pm b/2_0_13/t/filter/TestFilter/in_str_declined.pm
new file mode 100644
index 0000000..07bd69e
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_declined.pm
@@ -0,0 +1,69 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_declined;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK DECLINED M_POST);
+
+# make sure that if the input filter returns DECLINED without
+# reading/printing data the data flow is not broken
+sub handler {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+ $ctx->{invoked}++;
+ $filter->ctx($ctx);
+
+ # can't use $f->seen_eos, since we don't read the data, so
+ # we have to set the note on each invocation
+ $filter->r->notes->set(invoked => $ctx->{invoked});
+ #warn "filter was invoked $ctx->{invoked} times\n";
+
+ return Apache2::Const::DECLINED;
+}
+
+sub response {
+ my $r = shift;
+
+ my $data;
+ if ($r->method_number == Apache2::Const::M_POST) {
+ # consume the data so the input filter is invoked
+ $data = TestCommon::Utils::read_post($r);
+ }
+
+ plan $r, tests => 2;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ ok t_cmp(length $data, 20000, "the request body received ok");
+ }
+
+ # ~20k of input makes it four bucket brigades:
+ # - 2 full bucket brigades of 8k
+ # - 1 half full brigade ~4k
+ # - 1 bucket brigade with EOS bucket
+ # however different Apache versions may send extra bb or split
+ # data differently so we can't rely on the exact count
+ my $invoked = $r->notes->get('invoked') || 0;
+ ok $invoked > 1;
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_str_declined
+PerlResponseHandler TestFilter::in_str_declined::response
+
diff --git a/2_0_13/t/filter/TestFilter/in_str_declined_read.pm b/2_0_13/t/filter/TestFilter/in_str_declined_read.pm
new file mode 100644
index 0000000..06b9a9d
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_declined_read.pm
@@ -0,0 +1,57 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_declined_read;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK DECLINED M_POST);
+
+# a filter must not return DECLINED after calling $r->read, since the
+# latter already fetches the bucket brigade in which case it's up to
+# the user to complete reading it and send it out
+# thefore this filter must fail
+sub handler {
+ my $filter = shift;
+
+ # this causes a fetch of bb
+ $filter->read(my $buffer, 10);
+
+ return Apache2::Const::DECLINED;
+}
+
+sub response {
+ my $r = shift;
+
+ my $err;
+ if ($r->method_number == Apache2::Const::M_POST) {
+ # this should fail, because of the failing filter
+ eval { TestCommon::Utils::read_post($r) };
+ $err = $@;
+ }
+
+ plan $r, tests => 1;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ ok $err;
+ }
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_str_declined_read
+PerlResponseHandler TestFilter::in_str_declined_read::response
+
diff --git a/2_0_13/t/filter/TestFilter/in_str_lc.pm b/2_0_13/t/filter/TestFilter/in_str_lc.pm
new file mode 100644
index 0000000..60f5a80
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_lc.pm
@@ -0,0 +1,43 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_lc;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+sub handler {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ #warn "FILTER READ: $buffer\n";
+ $filter->print(lc $buffer);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ #warn "HANDLER READ: $data\n";
+ $r->print($data);
+ }
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_str_lc
+PerlResponseHandler TestFilter::in_str_lc::response
diff --git a/2_0_13/t/filter/TestFilter/in_str_msg.pm b/2_0_13/t/filter/TestFilter/in_str_msg.pm
new file mode 100644
index 0000000..e4582e2
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_msg.pm
@@ -0,0 +1,109 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_msg;
+
+# test:
+# - input connection filter rewriting the first HTTP header POST
+# - input request filter configured outside the resource container
+# should work just fine (via PerlOptions +MergeHandlers)
+# - input connection filter configured inside the resource container
+# is silently skipped (at the moment we can't complain about such,
+# since there could be connection filters from outside the resource
+# container that will get merged inside the resource dir_config
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache2::Filter);
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Brigade ();
+use APR::Bucket ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => ':common';
+
+my $from_url = '/input_filter.html';
+my $to_url = '/TestFilter__in_str_msg';
+
+sub con : FilterConnectionHandler {
+ my $filter = shift;
+
+ #warn "FILTER con CALLED\n";
+ my $ctx = $filter->ctx;
+
+ while ($filter->read(my $buffer, 1024)) {
+ #warn "FILTER READ: $buffer\n";
+ unless ($ctx) {
+ $buffer =~ s|POST $from_url|POST $to_url|;
+ $ctx = 1; # done
+ }
+ $filter->print($buffer);
+ }
+ $filter->ctx($ctx) if $ctx;
+
+ return Apache2::Const::OK;
+}
+
+sub req : FilterRequestHandler {
+ my $filter = shift;
+
+ #warn "FILTER req CALLED\n";
+ while ($filter->read(my $buffer, 1024)) {
+ $buffer =~ s/upcase me/UPCASED/;
+ $filter->print($buffer);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub con_skip : FilterConnectionHandler {
+ my $filter = shift;
+
+ #warn "FILTER con_skip CALLED\n";
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print("I'm a bogus filter. Don't run me\n");
+ }
+
+ return Apache2::Const::OK;
+}
+
+my $expected = "UPCASED";
+sub response {
+ my $r = shift;
+
+ my $received = TestCommon::Utils::read_post($r);
+
+ plan $r, tests => 1;
+
+ ok t_cmp($received, $expected,
+ "request filter must have upcased the data");
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestFilter::in_str_msg>
+ PerlModule TestFilter::in_str_msg
+ PerlInputFilterHandler TestFilter::in_str_msg::con
+
+ # this request filter is outside the resource container and it
+ # should work just fine because of PerlOptions +MergeHandlers
+ PerlInputFilterHandler TestFilter::in_str_msg::req
+
+ <Location /TestFilter__in_str_msg>
+ SetHandler modperl
+ PerlOptions +MergeHandlers
+ PerlInputFilterHandler TestFilter::in_str_msg::con_skip
+ PerlResponseHandler TestFilter::in_str_msg::response
+ </Location>
+
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_str_sandwich.pm b/2_0_13/t/filter/TestFilter/in_str_sandwich.pm
new file mode 100644
index 0000000..a7a9f19
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/in_str_sandwich.pm
@@ -0,0 +1,57 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::in_str_sandwich;
+
+# this test verifies whether the filter can pre-insert data (using
+# context) and post-insert data (using the seen_eos flag)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+sub handler {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+
+ unless ($ctx) {
+ $filter->print("HEADER\n");
+ $filter->ctx(1);
+ }
+
+ while ($filter->read(my $buffer, 1024)) {
+ #warn "FILTER READ: $buffer\n";
+ $filter->print($buffer);
+ }
+
+ if ($filter->seen_eos) {
+ $filter->print("TAIL\n");
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ #warn "HANDLER READ: $data\n";
+ $r->print($data);
+ }
+
+ return Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::in_str_sandwich
+PerlResponseHandler TestFilter::in_str_sandwich::response
diff --git a/2_0_13/t/filter/TestFilter/out_bbs_basic.pm b/2_0_13/t/filter/TestFilter/out_bbs_basic.pm
new file mode 100644
index 0000000..8071992
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_bbs_basic.pm
@@ -0,0 +1,73 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_bbs_basic;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+use APR::Brigade ();
+use APR::Bucket ();
+use APR::BucketType ();
+
+use Apache2::Const -compile => 'OK';
+
+#XXX: Not implemented yet, required by Test.pm
+sub Apache::TestToString::PRINTF {}
+
+sub handler {
+ my ($filter, $bb) = @_;
+
+ unless ($filter->ctx) {
+
+ Apache::TestToString->start;
+
+ plan tests => 4;
+
+ my $ba = $filter->r->connection->bucket_alloc;
+
+ #should only have 1 bucket from the response() below
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ ok $b->type->name;
+ ok $b->length == 2;
+ $b->read(my $data);
+ ok (defined $data and $data eq 'ok');
+ }
+
+ my $tests = Apache::TestToString->finish;
+
+ my $brigade = APR::Brigade->new($filter->r->pool, $ba);
+ my $b = APR::Bucket->new($ba, $tests);
+
+ $brigade->insert_tail($b);
+
+ my $ok = $brigade->first->type->name =~ /mod_perl/ ? 4 : 0;
+ $brigade->insert_tail(APR::Bucket->new($ba, "ok $ok\n"));
+
+ $brigade->insert_tail(APR::Bucket::eos_create($ba));
+
+ $filter->next->pass_brigade($brigade);
+
+ $filter->ctx(1); # flag that we have run this already
+ }
+
+ Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->puts("ok");
+
+ 0;
+}
+
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_bbs_basic
+PerlResponseHandler TestFilter::out_bbs_basic::response
diff --git a/2_0_13/t/filter/TestFilter/out_bbs_ctx.pm b/2_0_13/t/filter/TestFilter/out_bbs_ctx.pm
new file mode 100644
index 0000000..b6f2175
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_bbs_ctx.pm
@@ -0,0 +1,119 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_bbs_ctx;
+
+# this is the same test as TestFilter::context_stream, but uses the
+# bucket brigade API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use APR::Brigade ();
+use APR::Bucket ();
+use APR::BucketType ();
+
+use base qw(Apache2::Filter);
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK M_POST);
+use APR::Const -compile => ':common';
+
+use constant BLOCK_SIZE => 5003;
+
+sub handler {
+ my ($filter, $bb) = @_;
+
+ debug "filter got called";
+
+ my $c = $filter->c;
+ my $ba = $c->bucket_alloc;
+ my $bb_ctx = APR::Brigade->new($c->pool, $ba);
+
+ my $ctx = $filter->ctx;
+ $ctx->{invoked}++;
+
+ my $data = exists $ctx->{data} ? $ctx->{data} : '';
+
+ while (my $b = $bb->first) {
+
+ if ($b->is_eos) {
+ debug "got EOS";
+ # flush the remainings and send a stats signature
+ $bb_ctx->insert_tail(APR::Bucket->new($ba, "$data\n")) if $data;
+ my $sig = join "\n", "received $ctx->{blocks} complete blocks",
+ "filter invoked $ctx->{invoked} times\n";
+ $bb_ctx->insert_tail(APR::Bucket->new($ba, $sig));
+ $b->remove;
+ $bb_ctx->insert_tail($b);
+ last;
+ }
+
+ if ($b->read(my $bdata)) {
+ debug "got data";
+ $b->delete;
+ $data .= $bdata;
+ my $len = length $data;
+
+ my $blocks = 0;
+ if ($len >= BLOCK_SIZE) {
+ $blocks = int($len / BLOCK_SIZE);
+ $len = $len % BLOCK_SIZE;
+ $data = substr $data, $blocks*BLOCK_SIZE, $len;
+ $ctx->{blocks} += $blocks;
+ }
+ if ($blocks) {
+ my $nb = APR::Bucket->new($ba, "#" x $blocks);
+ $bb_ctx->insert_tail($nb);
+ }
+ }
+ else {
+ debug "got bucket with no data: type: " . $b->type->name;
+ $b->remove;
+ $bb_ctx->insert_tail($b);
+ }
+
+ }
+
+ $ctx->{data} = $data;
+ $filter->ctx($ctx);
+
+ my $rv = $filter->next->pass_brigade($bb_ctx);
+ return $rv unless $rv == APR::Const::SUCCESS;
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ # just to make sure that print() won't flush, or we would get the
+ # count wrong
+ local $| = 0;
+
+ # make sure that:
+ # - we send big enough data so it won't fit into one buffer
+ # - use chunk size which doesn't nicely fit into a buffer size, so
+ # we have something to store in the context between filter calls
+
+ my $blocks = 33;
+ my $block_size = BLOCK_SIZE + 1;
+ my $block = "x" x $block_size;
+ for (1..$blocks) {
+ $r->print($block);
+ $r->rflush; # so the filter reads a chunk at a time
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_bbs_ctx
+PerlResponseHandler TestFilter::out_bbs_ctx::response
+
diff --git a/2_0_13/t/filter/TestFilter/out_bbs_filebucket.pm b/2_0_13/t/filter/TestFilter/out_bbs_filebucket.pm
new file mode 100644
index 0000000..80f56dd
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_bbs_filebucket.pm
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_bbs_filebucket;
+
+# testing how the filter handles file buckets
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter;
+use Apache2::URI ();
+
+use APR::Brigade ();
+use APR::Bucket ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK);
+use APR::Const -compile => qw(SUCCESS);
+
+use constant BLOCK_SIZE => 5003;
+
+sub handler {
+ my ($filter, $bb) = @_;
+
+ debug "FILTER INVOKED";
+
+ my $cnt = 0;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+
+ $cnt++;
+ debug "reading bucket #$cnt";
+
+ last if $b->is_eos;
+
+ if (my $len = $b->read(my $data)) {
+ my $nb = APR::Bucket->new($bb->bucket_alloc, uc $data);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
+ }
+ }
+
+ return $filter->next->pass_brigade($bb);
+}
+
+sub response {
+ my $r = shift;
+
+ debug "\n-------- new request ----------";
+
+ $r->content_type('text/plain');
+
+ my $file = $r->args;
+ Apache2::URI::unescape_url($file);
+ $r->sendfile($file);
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_bbs_filebucket
+PerlResponseHandler TestFilter::out_bbs_filebucket::response
+PerlOutputFilterHandler TestFilter::out_bbs_filebucket::handler
diff --git a/2_0_13/t/filter/TestFilter/out_init_basic.pm b/2_0_13/t/filter/TestFilter/out_init_basic.pm
new file mode 100644
index 0000000..ccfa876
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_init_basic.pm
@@ -0,0 +1,87 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_init_basic;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use base qw(Apache2::Filter);
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant READ_SIZE => 1024;
+
+# this filter is expected to be called once
+# it'll set a note, with the count
+sub init : FilterInitHandler {
+ my $filter = shift;
+
+ #warn "**** init was invoked\n";
+
+ my $ctx = $filter->ctx;
+ $ctx->{init}++;
+ $filter->r->notes->set(init => $ctx->{init});
+ $filter->ctx($ctx);
+
+ #warn "**** init is exiting\n";
+
+ return Apache2::Const::OK;
+}
+
+# testing whether we can get the pre handler callback in evolved way
+sub get_pre_handler { return \&TestFilter::out_init_basic::init }
+
+# this filter adds a count for each time it is invoked
+sub transparent : FilterRequestHandler
+ FilterHasInitHandler(get_pre_handler())
+ {
+ my ($filter, $bb) = @_;
+
+ #warn "**** filter was invoked\n";
+
+ my $ctx = $filter->ctx;
+
+ $filter->print('run ', ++$ctx->{run}, "\n");
+
+ $filter->ctx($ctx);
+
+ my $rv = $filter->next->pass_brigade($bb);
+ return $rv unless $rv == APR::Const::SUCCESS;
+
+ #warn "**** filter is exiting\n";
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ #warn "**** content was invoked\n";
+
+ $r->content_type('text/plain');
+
+ my $data;
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $data = TestCommon::Utils::read_post($r);
+ }
+
+ $r->print('init ', $r->notes->get('init'), "\n");
+ $r->print($data) if $data;
+
+ #warn "**** content is exiting\n";
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_init_basic
+PerlResponseHandler TestFilter::out_init_basic::response
+PerlOutputFilterHandler TestFilter::out_init_basic::transparent
diff --git a/2_0_13/t/filter/TestFilter/out_str_api.pm b/2_0_13/t/filter/TestFilter/out_str_api.pm
new file mode 100644
index 0000000..b1c6bb7
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_api.pm
@@ -0,0 +1,99 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_api;
+
+# Test Apache2::FilterRec and Apache2::Filter accessors
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+use Apache2::FilterRec ();
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use Apache2::Const -compile => 'OK';
+
+my $response_data = "blah blah blah";
+
+#XXX: else pp_untie complains:
+#untie attempted while %d inner references still exist
+sub Apache2::Filter::UNTIE {}
+sub Apache2::Filter::PRINTF {}
+
+sub handler {
+ my $filter = shift;
+
+ my $data = '';
+ while ($filter->read(my $buffer, 1024)) {
+ $data .= $buffer;
+ }
+
+ tie *STDOUT, $filter;
+
+ plan tests => 8;
+
+ ok t_cmp($data, $response_data, "response data");
+
+ ok $filter->isa('Apache2::Filter');
+
+ {
+ my $frec = $filter->frec;
+
+ ok $frec->isa('Apache2::FilterRec');
+ ok t_cmp($frec->name, "modperl_request_output", '$frec->name');
+
+ my $next = $filter->next;
+ ok t_cmp($next->frec->name, "modperl_request_output",
+ '$filter->next->frec->name');
+
+ $next = $next->next;
+ # since we can't ensure that the next filter will be the same,
+ # as it's not under control, just check that we get some name
+ my $name = $next->frec->name;
+ t_debug("next->next name: $name");
+ ok $name;
+ }
+
+ my $r = $filter->r;
+
+ ok $r->isa('Apache2::RequestRec');
+
+ my $path = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+ ok t_cmp($r->uri, $path, "path");
+
+ untie *STDOUT;
+
+ # we have done the job
+ $filter->remove;
+
+ Apache2::Const::OK;
+}
+
+sub pass_through {
+ return Apache2::Const::DECLINED;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->puts($response_data);
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+PerlModule TestFilter::out_str_api
+<Location /TestFilter__out_str_api>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::out_str_api::response
+ PerlOutputFilterHandler TestFilter::out_str_api
+ PerlOutputFilterHandler TestFilter::out_str_api::pass_through
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/out_str_buffer.pm b/2_0_13/t/filter/TestFilter/out_str_buffer.pm
new file mode 100644
index 0000000..027e10f
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_buffer.pm
@@ -0,0 +1,99 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_buffer;
+
+# in this test we want to buffer the data, modify the length of the
+# response, set the c-l header and make sure that the client sees the
+# right thing
+#
+# notice that a bucket brigades based filter must be used. The streaming
+# API lets FLUSH buckets through which causes an early flush of HTTP
+# response headers
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use APR::Table ();
+use APR::Bucket ();
+use APR::Brigade ();
+
+use TestCommon::Utils ();
+
+use base qw(Apache2::Filter);
+
+use Apache2::Const -compile => qw(OK M_POST);
+use APR::Const -compile => ':common';
+
+sub flatten_bb {
+ my ($bb) = shift;
+
+ my $seen_eos = 0;
+
+ my @data;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ $seen_eos++, last if $b->is_eos;
+ $b->read(my $bdata);
+ push @data, $bdata;
+ }
+ return (join('', @data), $seen_eos);
+}
+
+sub handler {
+ my ($filter, $bb) = @_;
+
+ my $ctx = $filter->ctx;
+
+ # no need to unset the C-L header, since this filter makes sure to
+ # correct it before any headers go out.
+ #unless ($ctx) {
+ # $filter->r->headers_out->unset('Content-Length');
+ #}
+
+ my $data = exists $ctx->{data} ? $ctx->{data} : '';
+ $ctx->{invoked}++;
+ my ($bdata, $seen_eos) = flatten_bb($bb);
+ $bdata =~ s/-//g;
+ $data .= $bdata if $bdata;
+
+ if ($seen_eos) {
+ my $len = length $data;
+ $filter->r->headers_out->set('Content-Length', $len);
+ $filter->print($data) if $data;
+ }
+ else {
+ # store context for all but the last invocation
+ $ctx->{data} = $data;
+ $filter->ctx($ctx);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my $data = '';
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $data = TestCommon::Utils::read_post($r);
+ $r->headers_out->set('Content-Length' => length $data);
+ }
+
+ for my $chunk (split /0/, $data) {
+ $r->print($chunk);
+ $r->rflush; # so the filter reads a chunk at a time
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
+SetHandler modperl
+PerlModule TestFilter::out_str_buffer
+PerlResponseHandler TestFilter::out_str_buffer::response
+
diff --git a/2_0_13/t/filter/TestFilter/out_str_ctx.pm b/2_0_13/t/filter/TestFilter/out_str_ctx.pm
new file mode 100644
index 0000000..762c60b
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_ctx.pm
@@ -0,0 +1,92 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_ctx;
+
+# this is the same test as TestFilter::context, but uses the streaming
+# API
+
+use strict;
+use warnings;# FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use base qw(Apache2::Filter);
+
+use Apache2::Const -compile => qw(OK M_POST);
+use APR::Const -compile => ':common';
+
+use constant BLOCK_SIZE => 5003;
+use constant READ_SIZE => 1024;
+
+sub handler {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+ my $data = exists $ctx->{data} ? $ctx->{data} : '';
+ $ctx->{invoked}++;
+
+ while ($filter->read(my $bdata, READ_SIZE)) {
+ $data .= $bdata;
+ my $len = length $data;
+
+ my $blocks = 0;
+ if ($len >= BLOCK_SIZE) {
+ $blocks = int($len / BLOCK_SIZE);
+ $len = $len % BLOCK_SIZE;
+ $data = substr $data, $blocks*BLOCK_SIZE, $len;
+ $ctx->{blocks} += $blocks;
+ }
+ if ($blocks) {
+ $filter->print("#" x $blocks);
+ }
+ }
+
+ if ($filter->seen_eos) {
+ # flush the remaining data and add a statistics signature
+ $filter->print("$data\n") if $data;
+ my $sig = join "\n", "received $ctx->{blocks} complete blocks",
+ "filter invoked $ctx->{invoked} times\n";
+ $filter->print($sig);
+ }
+ else {
+ # store context for all but the last invocation
+ $ctx->{data} = $data;
+ $filter->ctx($ctx);
+ }
+
+ return Apache2::Const::OK;
+}
+
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ # just to make sure that print() flushes, or we would get the
+ # count wrong
+ local $| = 1;
+
+ # make sure that
+ # - we send big enough data so it won't fit into one buffer
+ # - use chunk size which doesn't nicely fit into a buffer size, so
+ # we have something to store in the context between filter calls
+
+ my $blocks = 33;
+ my $block_size = BLOCK_SIZE + 1;
+ my $block = "x" x $block_size;
+ for (1..$blocks) {
+ $r->print($block);
+ $r->rflush; # so the filter reads a chunk at a time
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
+SetHandler modperl
+PerlModule TestFilter::out_str_ctx
+PerlResponseHandler TestFilter::out_str_ctx::response
+
diff --git a/2_0_13/t/filter/TestFilter/out_str_declined.pm b/2_0_13/t/filter/TestFilter/out_str_declined.pm
new file mode 100644
index 0000000..0f4cbf6
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_declined.pm
@@ -0,0 +1,82 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_declined;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+use constant READ_SIZE => 1024;
+
+# make sure that if the input filter returns DECLINED without
+# reading/printing data the data flow is not broken
+sub decline {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+ $ctx->{invoked}++;
+ $filter->ctx($ctx);
+
+ # can't use $f->seen_eos, since we don't read the data, so
+ # we have to set the note on each invocation
+ $filter->r->notes->set(invoked => $ctx->{invoked});
+ #warn "decline filter was invoked $ctx->{invoked} times\n";
+
+ return Apache2::Const::DECLINED;
+}
+
+# this filter ignores all the data that comes through, though on the
+# last invocation it prints how many times the filter 'decline' was called
+# which it could count by itself, but we want to test that
+# 'return Apache2::Const::DECLINED' works properly in output filters
+sub black_hole {
+ my $filter = shift;
+
+ my $ctx = $filter->ctx;
+ $ctx->{invoked}++;
+ $filter->ctx($ctx);
+ #warn "black_hole filter was invoked $ctx->{invoked} times\n";
+
+ while ($filter->read(my $data, READ_SIZE)) {
+ #warn "black_hole data: $data\n";
+ # let the data fall between the chairs
+ }
+
+ if ($filter->seen_eos) {
+ my $invoked = $filter->r->notes->get('invoked') || 0;
+ $filter->print($invoked);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ # just to make sure that print() won't flush, or we would get the
+ # count wrong
+ local $| = 0;
+
+ $r->content_type('text/plain');
+ for (1..10) {
+ $r->print("a"); # this buffers the data
+ $r->rflush; # this sends the data in the buffer + flush bucket
+ }
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_str_declined
+PerlResponseHandler TestFilter::out_str_declined::response
+PerlOutputFilterHandler TestFilter::out_str_declined::decline
+PerlOutputFilterHandler TestFilter::out_str_declined::black_hole
diff --git a/2_0_13/t/filter/TestFilter/out_str_eval.pm b/2_0_13/t/filter/TestFilter/out_str_eval.pm
new file mode 100644
index 0000000..0201bcd
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_eval.pm
@@ -0,0 +1,45 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_eval;
+
+# at some point there was a problem when eval {} in a non-filter
+# handler wasn't functioning when a filter was involved. the $@ value
+# was getting lost when t_cmp was doing print of debug values. and a
+# new invocation of a filter handler resets the value of $@.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+# dummy pass_through filter was good enough to trigger the problem
+sub handler {
+ return Apache2::Const::DECLINED;
+}
+
+sub response {
+ my $r = shift;
+
+ plan $r, tests => 1;
+ # test that filters don't reset $@
+ eval { i_do_not_exist_really_i_do_not() };
+ # trigger the filter invocation, before using $@
+ $r->print("# whatever");
+ $r->rflush;
+ ok t_cmp($@, qr/Undefined subroutine/, "some croak");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_str_eval
+PerlResponseHandler TestFilter::out_str_eval::response
+
diff --git a/2_0_13/t/filter/TestFilter/out_str_lc.pm b/2_0_13/t/filter/TestFilter/out_str_lc.pm
new file mode 100644
index 0000000..8325b38
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_lc.pm
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_lc;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Filter ();
+
+use TestCommon::Utils;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+
+ # test that read() returns tainted data
+ die "read() has returned untainted data"
+ unless TestCommon::Utils::is_tainted($buffer);
+
+ $filter->print(lc $buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
+<Location /top_dir>
+ PerlOutputFilterHandler TestFilter::out_str_lc
+</Location>
+<IfModule mod_alias.c>
+ Alias /top_dir @top_dir@
+</IfModule>
diff --git a/2_0_13/t/filter/TestFilter/out_str_remove.pm b/2_0_13/t/filter/TestFilter/out_str_remove.pm
new file mode 100644
index 0000000..cc3d14d
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_remove.pm
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_remove;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+
+use Apache2::Const -compile => qw(OK);
+
+use constant READ_SIZE => 1024;
+
+# this filter reads the first bb, upcases the data in it and removes itself
+sub upcase_n_remove {
+ my $filter = shift;
+
+ #warn "filter upcase_n_remove called\n";
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print(uc $buffer);
+ }
+
+ $filter->remove;
+
+ return Apache2::Const::OK;
+}
+
+# this filter inserts underscores after each character it receives
+sub insert_underscores {
+ my $filter = shift;
+
+ #warn "filter insert_underscores called\n";
+ while ($filter->read(my $buffer, 1024)) {
+ $buffer =~ s/(.)/$1_/g;
+ $filter->print($buffer);
+ }
+
+ return Apache2::Const::OK;
+}
+
+
+sub response {
+ my $r = shift;
+
+ # just to make sure that print() won't flush, or we would get the
+ # count wrong
+ local $| = 0;
+
+ $r->content_type('text/plain');
+ $r->print("Foo");
+ $r->rflush; # this sends the data in the buffer + flush bucket
+ $r->print("bar");
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_str_remove
+PerlResponseHandler TestFilter::out_str_remove::response
+PerlOutputFilterHandler TestFilter::out_str_remove::insert_underscores
+PerlOutputFilterHandler TestFilter::out_str_remove::upcase_n_remove
diff --git a/2_0_13/t/filter/TestFilter/out_str_req_eos.pm b/2_0_13/t/filter/TestFilter/out_str_req_eos.pm
new file mode 100644
index 0000000..866c8a1
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_req_eos.pm
@@ -0,0 +1,83 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_req_eos;
+
+# here we test how EOS is passed from one streaming filter to another,
+# making sure that it's not lost
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+my $prefix = 'PREFIX_';
+my $suffix = '_SUFFIX';
+
+sub add_prefix {
+ my $filter = shift;
+
+ #warn "add_prefix called\n";
+
+ unless ($filter->ctx) {
+ $filter->print($prefix);
+ $filter->ctx(1);
+ }
+
+ while ($filter->read(my $buffer, 1024)){
+ #warn "add_prefix read: [$buffer]\n";
+ $filter->print($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub add_suffix {
+ my $filter = shift;
+
+ #warn "add_suffix called\n";
+
+ while ($filter->read(my $buffer, 1024)){
+ #warn "add_suffix read: [$buffer]\n";
+ $filter->print($buffer);
+ }
+
+ if ($filter->seen_eos) {
+ $filter->print($suffix);
+ $filter->ctx(1);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print(TestCommon::Utils::read_post($r));
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ PerlModule TestFilter::out_str_req_eos
+ <Location /TestFilter__out_str_req_eos>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::out_str_req_eos
+ PerlOutputFilterHandler TestFilter::out_str_req_eos::add_prefix
+ PerlOutputFilterHandler TestFilter::out_str_req_eos::add_suffix
+ </Location>
+</NoAutoConfig>
+
+
+
+
diff --git a/2_0_13/t/filter/TestFilter/out_str_req_mix.pm b/2_0_13/t/filter/TestFilter/out_str_req_mix.pm
new file mode 100644
index 0000000..771cb09
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_req_mix.pm
@@ -0,0 +1,87 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_req_mix;
+
+# in this test we verify that we can preserve the mixed order of
+# modperl and non-modperl filters using the PerlSetOutputFilter
+# directive, instead of SetOutputFilter for non-modperl filters.
+#
+# response handler prints a mangled SSI directive:
+# <!--#include virtual="/includes/REMOVEclear.shtml" -->
+# (which it receives via POST from the client)
+#
+# adjust() filter is configured to be called first and it removes the
+# string 'REMOVE' from the response handler's output, so that SSI will
+# find the fixed resource specification:
+# <!--#include virtual="/includes/clear.shtml" -->
+#
+# the INCLUDES filter, which is configured to be next on the stack
+# (mod_include) processes the directive and returns the contents of
+# file "/includes/clear.shtml", which is:
+# This is a REMOVEclear text
+#
+# finally the second mod_perl filter (which happens to be the same
+# adjust() filter, but to all purposes it's a separate filter)
+# configured to run after the INCLUDES filter fixes the data sent by
+# the INCLUDES filter to be:
+# This is a clear text
+#
+# and this is what the client is expecting to receive
+#
+# WARNING: notice that the adjust() filter assumes that it'll receive
+# the word REMOVE in a single bucket, which is good enough for the
+# test because we control all the used filters and normally Apache
+# core filters won't split short data into several buckets. However
+# filter developers shouldn't make any assumptions, since any data can
+# be split by any of the upstream filters.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+sub adjust {
+ my $filter = shift;
+
+ #warn "adjust called\n";
+
+ while ($filter->read(my $buffer, 1024)){
+ $buffer =~ s/REMOVE//;
+ $filter->print($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ $r->print(TestCommon::Utils::read_post($r));
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ PerlModule TestFilter::out_str_req_mix
+ <Location /TestFilter__out_str_req_mix>
+ Options +Includes
+ PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust
+ PerlSetOutputFilter INCLUDES
+ PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust
+ SetHandler modperl
+ PerlResponseHandler TestFilter::out_str_req_mix
+ </Location>
+</NoAutoConfig>
+
+
+
+
diff --git a/2_0_13/t/filter/TestFilter/out_str_reverse.pm b/2_0_13/t/filter/TestFilter/out_str_reverse.pm
new file mode 100644
index 0000000..5237f1f
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_reverse.pm
@@ -0,0 +1,82 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_reverse;
+
+# this filter tests how the data can be set-aside between filter
+# invocations. here we collect a single line (which terminates with a
+# new line) before we apply the reversing transformation.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+use constant BUFF_LEN => 2;
+use constant signature => "Reversed by mod_perl 2.0\n";
+
+sub handler {
+ my $f = shift;
+ #warn "called\n";
+
+ my $leftover = $f->ctx;
+
+ # We are about to change the length of the response body. Hence, we
+ # have to adjust the content-length header.
+ unless (defined $leftover) { # 1st invocation
+ $f->r->headers_out->{'Content-Length'}+=length signature
+ if exists $f->r->headers_out->{'Content-Length'};
+ }
+
+ while ($f->read(my $buffer, BUFF_LEN)) {
+ #warn "buffer: [$buffer]\n";
+ $buffer = $leftover . $buffer if defined $leftover;
+ $leftover = undef;
+ while ($buffer =~ /([^\r\n]*)([\r\n]*)/g) {
+ $leftover = $1, last unless $2;
+ $f->print(scalar(reverse $1), $2);
+ }
+ }
+
+ if ($f->seen_eos) {
+ $f->print(scalar reverse $leftover) if defined $leftover;
+ $f->print(signature);
+ }
+ else {
+ $f->ctx($leftover) if defined $leftover;
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ # unbuffer stdout, so we get the data split across several bbs
+ local $_ = 1;
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ $r->print($_) for grep length $_, split /(.{5})/, $data;
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<Base>
+ PerlModule TestFilter::out_str_reverse
+ <LocationMatch "/filter/reverse.txt">
+ PerlOutputFilterHandler TestFilter::out_str_reverse
+ </LocationMatch>
+</Base>
+
+SetHandler modperl
+PerlResponseHandler TestFilter::out_str_reverse::response
+
diff --git a/2_0_13/t/filter/TestFilter/out_str_subreq_default.pm b/2_0_13/t/filter/TestFilter/out_str_subreq_default.pm
new file mode 100644
index 0000000..2ffcc0f
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_subreq_default.pm
@@ -0,0 +1,82 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_subreq_default;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache2::Filter ();
+
+use Apache2::Const -compile => qw(OK);
+
+# include the contents of a subrequest
+# in the filter, a la mod_include's
+# <!--#include virtual="/subrequest" -->
+
+sub include {
+
+ my $filter = shift;
+
+ unless ($filter->ctx) {
+ # don't forget to remove the C-L header
+ $filter->r->headers_out->unset('Content-Length');
+
+ $filter->ctx(1);
+ }
+
+ while ($filter->read(my $buffer, 1024)){
+
+ if ($buffer eq "<tag>\n") {
+ my $sub = $filter->r->lookup_uri('/default_subrequest/subrequest.txt');
+ my $rc = $sub->run;
+ }
+ else {
+ # send all other data along unaltered
+ $filter->print($buffer);
+ }
+
+ }
+
+ # add our own at the end
+ if ($filter->seen_eos) {
+ $filter->print("filter\n");
+ $filter->ctx(1);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ $r->print("content\n");
+ $r->rflush;
+ $r->print("<tag>\n");
+ $r->rflush;
+ $r->print("more content\n");
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_str_subreq_default
+PerlResponseHandler TestFilter::out_str_subreq_default::response
+PerlOutputFilterHandler TestFilter::out_str_subreq_default::include
+
+<IfModule mod_alias.c>
+ Alias /default_subrequest @DocumentRoot@/filter
+</IfModule>
+
+<Location /default_subrequest>
+ SetHandler default-handler
+</Location>
diff --git a/2_0_13/t/filter/TestFilter/out_str_subreq_modperl.pm b/2_0_13/t/filter/TestFilter/out_str_subreq_modperl.pm
new file mode 100644
index 0000000..ba3b4a4
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/out_str_subreq_modperl.pm
@@ -0,0 +1,89 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestFilter::out_str_subreq_modperl;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache2::Filter ();
+
+use Apache2::Const -compile => qw(OK);
+
+# include the contents of a subrequest
+# in the filter, a la mod_include's
+# <!--#include virtual="/subrequest" -->
+
+sub include {
+
+ my $filter = shift;
+
+ unless ($filter->ctx) {
+ # don't forget to remove the C-L header
+ $filter->r->headers_out->unset('Content-Length');
+
+ $filter->ctx(1);
+ }
+
+ while ($filter->read(my $buffer, 1024)){
+
+ if ($buffer eq "<tag>\n") {
+ my $sub = $filter->r->lookup_uri('/modperl_subrequest');
+ my $rc = $sub->run;
+ }
+ else {
+ # send all other data along unaltered
+ $filter->print($buffer);
+ }
+
+ }
+
+ # add our own at the end
+ if ($filter->seen_eos) {
+ $filter->print("filter\n");
+ $filter->ctx(1);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub subrequest {
+
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->print("modperl subrequest\n");
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ $r->print("content\n");
+ $r->rflush;
+ $r->print("<tag>\n");
+ $r->rflush;
+ $r->print("more content\n");
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule TestFilter::out_str_subreq_modperl
+PerlResponseHandler TestFilter::out_str_subreq_modperl::response
+PerlOutputFilterHandler TestFilter::out_str_subreq_modperl::include
+
+<Location /modperl_subrequest>
+ SetHandler modperl
+ PerlResponseHandler TestFilter::out_str_subreq_modperl::subrequest
+</Location>
diff --git a/2_0_13/t/filter/TestFilter/with_subrequest.pm b/2_0_13/t/filter/TestFilter/with_subrequest.pm
new file mode 100644
index 0000000..1448ee4
--- /dev/null
+++ b/2_0_13/t/filter/TestFilter/with_subrequest.pm
@@ -0,0 +1,38 @@
+package TestFilter::with_subrequest;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Filter ();
+use Apache2::SubRequest ();
+
+use TestCommon::Utils;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $f = shift;
+ my $r = $f->r;
+
+ my $subr;
+ while ($f->read(my $buffer, 1024)) {
+ $f->print(lc $buffer);
+ if (!$subr) {
+ $subr = $r->lookup_uri($r->uri);
+ my $rc = $subr->run;
+ }
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
+<Location /with_subrequest>
+ PerlOutputFilterHandler TestFilter::with_subrequest
+</Location>
+
+<IfModule mod_alias.c>
+ Alias /with_subrequest @top_dir@
+</IfModule>
diff --git a/2_0_13/t/filter/both_str_con_add.t b/2_0_13/t/filter/both_str_con_add.t
new file mode 100644
index 0000000..1937406
--- /dev/null
+++ b/2_0_13/t/filter/both_str_con_add.t
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = qw(MODPERL 2.0 RULES);
+
+# blocking socket bug fixed in 2.0.52
+my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52');
+
+plan tests => 1 + @test_strings, $ok;
+
+my $module = "TestFilter::both_str_con_add";
+my $socket = Apache::TestRequest::vhost_socket($module);
+
+ok $socket;
+
+for my $str (@test_strings) {
+ print $socket "$str\n";
+ chomp(my $reply = <$socket>||'');
+ $str = lc $str;
+ $str =~ s/modperl/mod_perl/;
+ ok t_cmp($reply, $str);
+}
diff --git a/2_0_13/t/filter/both_str_native_remove.t b/2_0_13/t/filter/both_str_native_remove.t
new file mode 100644
index 0000000..4dbc1c1
--- /dev/null
+++ b/2_0_13/t/filter/both_str_native_remove.t
@@ -0,0 +1,60 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 8, need 'deflate', 'include',
+ need_min_module_version("Compress::Zlib", "1.09");
+
+require Compress::Zlib;
+
+my $base = '/TestFilter__both_str_native_remove';
+
+# 1. check if DEFLATE input and INCLUDES output filter work
+{
+ my $location = $base;
+ my $received = POST_BODY $location,
+ content => Compress::Zlib::memGzip('gzipped text'),
+ 'Content-Encoding' => "gzip";
+
+ ok t_cmp $received, qr/xSSI OK/, "INCLUDES filter";
+
+ ok t_cmp $received, qr/content: gzipped text/, "DEFLATE filter";
+}
+
+
+# 2. check if DEFLATE input and INCLUDES output filter can be removed
+{
+ my $location = "$base?remove";
+ my $received = POST_BODY $location, content => 'plain text';
+
+ ok t_cmp $received,
+ qr/input1: [\w,]+deflate/,
+ "DEFLATE filter is present";
+
+ ok !t_cmp $received,
+ qr/input2: [\w,]+deflate/,
+ "DEFLATE filter is removed";
+
+ ok t_cmp $received,
+ qr/content: plain text/,
+ "DEFLATE filter wasn't invoked";
+
+ ok t_cmp $received,
+ qr/output1: modperl_request_output,includes,modperl_request_output,/,
+ "INCLUDES filter is present";
+
+ ok t_cmp $received,
+ qr/output2: modperl_request_output,(?!includes)/,
+ "INCLUDES filter is removed";
+
+ ok t_cmp $received,
+ qr/x<!--#echo var="SSI_TEST" -->x/,
+ "INCLUDES filter wasn't invoked";
+
+}
+
+
diff --git a/2_0_13/t/filter/both_str_req_add.t b/2_0_13/t/filter/both_str_req_add.t
new file mode 100644
index 0000000..867ebf8
--- /dev/null
+++ b/2_0_13/t/filter/both_str_req_add.t
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $data = join ' ', 'A'..'Z', 0..9;
+my $expected = lc $data; # that's what the input filter does
+$expected =~ s/\s+//g; # that's what the output filter does
+$expected .= "end"; # that's what the anon output filter does
+my $location = '/TestFilter__both_str_req_add';
+my $response = POST_BODY $location, content => $data;
+ok t_cmp($response, $expected, "lc input and reverse output filters");
+
diff --git a/2_0_13/t/filter/both_str_req_mix.t b/2_0_13/t/filter/both_str_req_mix.t
new file mode 100644
index 0000000..fa44462
--- /dev/null
+++ b/2_0_13/t/filter/both_str_req_mix.t
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1, need 'deflate', 'include',
+ need_min_module_version("Compress::Zlib", "1.09");
+
+require Compress::Zlib;
+my $location = '/TestFilter__both_str_req_mix';
+
+my $request_orig = '<!--#include INPUTvirtual="/includes/OUTPUTclear.shtml" -->';
+my $response_orig = 'This is a clear text';
+
+# gzip already produces data in a network order, so no extra
+# transformation seem to be necessary
+
+my $content = Compress::Zlib::memGzip($request_orig);
+my $response_raw = POST_BODY $location,
+ content => $content,
+ 'Accept-Encoding' => "gzip",
+ 'Content-Encoding' => "gzip";
+
+#t_debug($response_raw);
+my $response_clear = Compress::Zlib::memGunzip($response_raw);
+#t_debug($response_clear);
+
+my $expected = $response_orig;
+(my $received = $response_clear) =~ s{\r?\n$}{};
+
+ok t_cmp($received, $expected,
+ "mixing httpd and mod_perl filters, while preserving order");
+
diff --git a/2_0_13/t/filter/both_str_req_proxy.t b/2_0_13/t/filter/both_str_req_proxy.t
new file mode 100644
index 0000000..ae91fc7
--- /dev/null
+++ b/2_0_13/t/filter/both_str_req_proxy.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+my @modules = qw(mod_proxy proxy_http.c);
+push @modules, 'mod_access_compat.c' if have_min_apache_version("2.4.0");
+plan tests => 1, need need_module(@modules), need_access;
+
+my $data = join ' ', 'A'..'Z', 0..9;
+my $expected = lc $data; # that's what the input filter does
+$expected =~ s/\s+//g; # that's what the output filter does
+my $location = '/TestFilter__both_str_req_proxy/foo';
+my $response = POST_BODY $location, content => $data;
+ok t_cmp($response, $expected, "lc input and reverse output filters");
+
diff --git a/2_0_13/t/filter/in_autoload.t b/2_0_13/t/filter/in_autoload.t
new file mode 100644
index 0000000..d57ae30
--- /dev/null
+++ b/2_0_13/t/filter/in_autoload.t
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_autoload';
+
+my $data = "[Foo BaR] ";
+my $expected = lc $data;
+my $received = POST_BODY $location, content => $data;
+
+ok t_cmp($received, $expected, "input stream filter lc autoloaded")
+
diff --git a/2_0_13/t/filter/in_bbs_body.t b/2_0_13/t/filter/in_bbs_body.t
new file mode 100644
index 0000000..8ca5e5c
--- /dev/null
+++ b/2_0_13/t/filter/in_bbs_body.t
@@ -0,0 +1,14 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+
+my $location = '/TestFilter__in_bbs_body';
+
+print GET_BODY_ASSERT $location;
+
+for my $x (2..3) {
+ my $data = scalar reverse "ok $x\n";
+ print POST_BODY_ASSERT $location, content => $data;
+}
diff --git a/2_0_13/t/filter/in_bbs_consume.t b/2_0_13/t/filter/in_bbs_consume.t
new file mode 100644
index 0000000..3defa2b
--- /dev/null
+++ b/2_0_13/t/filter/in_bbs_consume.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_bbs_consume';
+
+# send a message bigger than 8k, so to make sure that the input filter
+# will get more than one bucket brigade with data.
+my $length = 40 * 1024 + 7; # ~40k+ (~6 incoming bucket brigades)
+my $expected = join '', 'a'..'z';
+my $data = $expected . "x" x $length;
+my $received = POST_BODY $location, content => $data;
+
+ok t_cmp($received, $expected, "input bbs filter full consume")
diff --git a/2_0_13/t/filter/in_bbs_inject_header.t b/2_0_13/t/filter/in_bbs_inject_header.t
new file mode 100644
index 0000000..e45b047
--- /dev/null
+++ b/2_0_13/t/filter/in_bbs_inject_header.t
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache::TestRequest;
+
+my $module = 'TestFilter::in_bbs_inject_header';
+my $location = "/" . Apache::TestRequest::module2path($module);
+
+Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl
+Apache::TestRequest::module($module);
+
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+my $content = "This body shouldn't be seen by the filter";
+
+my $header1_key = 'X-My-Protocol';
+my $header1_val = 'POST-IT';
+
+my %headers = (
+ 'X-Extra-Header2' => 'Value 2',
+ 'X-Extra-Header3' => 'Value 3',
+);
+
+my $keep_alive_times = 4;
+my $non_keep_alive_times = 4;
+my $tests = 2 + keys %headers;
+my $times = $non_keep_alive_times + $keep_alive_times + 1;
+
+plan tests => $tests * $times;
+
+# try non-keepalive conn
+validate(POST($location, content => $content)) for 1..$non_keep_alive_times;
+
+# try keepalive conns
+Apache::TestRequest::user_agent(reset => 1, keep_alive => 1);
+validate(POST($location, content => $content)) for 1..$keep_alive_times;
+
+# try non-keepalive conn
+Apache::TestRequest::user_agent(reset => 1, keep_alive => 0);
+validate(POST($location, content => $content));
+
+# 4 sub-tests
+sub validate {
+ my $res = shift;
+
+ die join "\n",
+ "request has failed (the response code was: " . $res->code . ")",
+ "see t/logs/error_log for more details\n" unless $res->is_success;
+
+ ok t_cmp($res->content, $content, "body");
+
+ ok t_cmp($res->header($header1_key),
+ $header1_val,
+ "injected header $header1_key");
+
+ for my $key (sort keys %headers) {
+ ok t_cmp($res->header($key),
+ $headers{$key},
+ "injected header $key");
+ }
+}
diff --git a/2_0_13/t/filter/in_bbs_msg.t b/2_0_13/t/filter/in_bbs_msg.t
new file mode 100644
index 0000000..02a3027
--- /dev/null
+++ b/2_0_13/t/filter/in_bbs_msg.t
@@ -0,0 +1,16 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::Test ();
+use Apache::TestUtil;
+
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+my $module = 'TestFilter::in_bbs_msg';
+
+Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl
+Apache::TestRequest::module($module);
+
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+print GET_BODY_ASSERT "/input_filter.html";
diff --git a/2_0_13/t/filter/in_bbs_underrun.t b/2_0_13/t/filter/in_bbs_underrun.t
new file mode 100644
index 0000000..70e999b
--- /dev/null
+++ b/2_0_13/t/filter/in_bbs_underrun.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_bbs_underrun';
+
+# send a message of about 40k, so to make sure that the input filter
+# will get several bucket brigades with data (about 8k/brigade)
+my $length = 40 * 1024 + 7; # ~40k+ (~6 incoming bucket brigades)
+my $data = "x" x $length;
+my $received = POST_BODY $location, content => $data;
+my $expected = "read $length chars";
+
+ok t_cmp($received, $expected, "input bbs filter underrun test")
diff --git a/2_0_13/t/filter/in_error.t b/2_0_13/t/filter/in_error.t
new file mode 100644
index 0000000..0ac9662
--- /dev/null
+++ b/2_0_13/t/filter/in_error.t
@@ -0,0 +1,15 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_error';
+
+my $res = POST $location, content => 'foo';
+ok t_cmp($res->code, 500, "an error in a filter should cause 500");
+
diff --git a/2_0_13/t/filter/in_init_basic.t b/2_0_13/t/filter/in_init_basic.t
new file mode 100644
index 0000000..a82ffaa
--- /dev/null
+++ b/2_0_13/t/filter/in_init_basic.t
@@ -0,0 +1,17 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $content = "content ok\n";
+# older httpds may run the input request filter twice
+my $expected = join '', $content, "init 1\n", "run [12]\n";
+
+my $location = '/TestFilter__in_init_basic';
+my $response = POST_BODY $location, content => $content;
+ok t_cmp($response, qr/$expected/, "test filter init functionality");
diff --git a/2_0_13/t/filter/in_str_bin_data.t b/2_0_13/t/filter/in_str_bin_data.t
new file mode 100644
index 0000000..da801bd
--- /dev/null
+++ b/2_0_13/t/filter/in_str_bin_data.t
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 4;
+
+my $base = "/TestFilter__in_str_bin_data";
+my @locations = map {$base . $_ } ('', '_filter');
+my $expected = "123\001456\000789";
+
+# test the binary data read/print w/ and w/o pass through filter
+for my $location (@locations) {
+ my $received = POST_BODY_ASSERT $location, content => $expected;
+
+ ok t_cmp(length($received),
+ length($expected),
+ "$location binary response length");
+
+ ok t_cmp($received,
+ $expected,
+ "$location binary response data");
+}
+
diff --git a/2_0_13/t/filter/in_str_consume.t b/2_0_13/t/filter/in_str_consume.t
new file mode 100644
index 0000000..7ad619d
--- /dev/null
+++ b/2_0_13/t/filter/in_str_consume.t
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# see the explanations in in_str_consume.pm
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_str_consume';
+
+my $data = "*" x 80000; # about 78K => ~10 bbs
+my $expected = 105;
+
+t_debug "sent " . length($data) . "B, expecting ${expected}B to make through";
+
+my $received = POST_BODY $location, content => $data;
+
+ok t_cmp($received, $expected, "input stream filter partial consume")
diff --git a/2_0_13/t/filter/in_str_declined.t b/2_0_13/t/filter/in_str_declined.t
new file mode 100644
index 0000000..f22db3b
--- /dev/null
+++ b/2_0_13/t/filter/in_str_declined.t
@@ -0,0 +1,12 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest 'POST_BODY_ASSERT';;
+
+my $location = '/TestFilter__in_str_declined';
+
+my $chunk = "1234567890";
+my $data = $chunk x 2000;
+
+print POST_BODY_ASSERT $location, content => $data;
diff --git a/2_0_13/t/filter/in_str_declined_read.t b/2_0_13/t/filter/in_str_declined_read.t
new file mode 100644
index 0000000..94b6618
--- /dev/null
+++ b/2_0_13/t/filter/in_str_declined_read.t
@@ -0,0 +1,12 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest 'POST_BODY_ASSERT';;
+
+my $location = '/TestFilter__in_str_declined_read';
+
+my $chunk = "1234567890";
+my $data = $chunk x 2000;
+
+print POST_BODY_ASSERT $location, content => $data;
diff --git a/2_0_13/t/filter/in_str_lc.t b/2_0_13/t/filter/in_str_lc.t
new file mode 100644
index 0000000..e2dceaf
--- /dev/null
+++ b/2_0_13/t/filter/in_str_lc.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_str_lc';
+
+my $chunk = "[Foo BaR] ";
+my $data = $chunk x 250;
+my $expected = lc $data;
+my $received = POST_BODY $location, content => $data;
+
+ok t_cmp($received, $expected, "input stream filter lc")
+
diff --git a/2_0_13/t/filter/in_str_msg.t b/2_0_13/t/filter/in_str_msg.t
new file mode 100644
index 0000000..74a781f
--- /dev/null
+++ b/2_0_13/t/filter/in_str_msg.t
@@ -0,0 +1,16 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::Test ();
+use Apache::TestUtil;
+
+use Apache::TestRequest 'POST_BODY_ASSERT';
+
+my $module = 'TestFilter::in_str_msg';
+
+Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl
+Apache::TestRequest::module($module);
+
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+print POST_BODY_ASSERT "/input_filter.html", content => "upcase me";
diff --git a/2_0_13/t/filter/in_str_sandwich.t b/2_0_13/t/filter/in_str_sandwich.t
new file mode 100644
index 0000000..a9d7ef6
--- /dev/null
+++ b/2_0_13/t/filter/in_str_sandwich.t
@@ -0,0 +1,17 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = '/TestFilter__in_str_sandwich';
+
+my $expected = join "\n", qw(HEADER BODY TAIL), '';
+my $received = POST_BODY $location, content => "BODY\n";
+
+ok t_cmp($received, $expected, "input stream filter sandwich")
+
diff --git a/2_0_13/t/filter/out_apache.t b/2_0_13/t/filter/out_apache.t
new file mode 100644
index 0000000..79c1325
--- /dev/null
+++ b/2_0_13/t/filter/out_apache.t
@@ -0,0 +1,38 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# test the situation where a native apache response filter is
+# configured outside the <Location> block with PerlSet*Filter
+# directive. In this case we need to make sure that mod_perl doesn't
+# try to add it as connection filter
+
+# see the server side config in t/conf/extra.conf.in
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest 'GET_BODY_ASSERT';
+use TestCommon::LogDiff;
+use File::Spec::Functions qw(catfile);
+
+my $path = catfile Apache::Test::vars('serverroot'),
+ qw(logs error_log);
+
+plan tests => 2, need 'include', 'HTML::HeadParser';
+
+my $module = 'filter_out_apache';
+my $config = Apache::Test::config();
+
+Apache::TestRequest::module($module);
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+my $logdiff = TestCommon::LogDiff->new($path);
+
+my $expected = qr/welcome to/;
+my $response = GET_BODY_ASSERT "http://$hostport/";
+ok t_cmp $response, qr/$expected/, "success";
+
+ok !t_cmp $logdiff->diff,
+ qr/content filter was added without a request: includes/,
+ "shouldn't [error] complain in error_log";
diff --git a/2_0_13/t/filter/out_bbs_ctx.t b/2_0_13/t/filter/out_bbs_ctx.t
new file mode 100644
index 0000000..8e16c98
--- /dev/null
+++ b/2_0_13/t/filter/out_bbs_ctx.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $blocks = 33;
+my $invoked = 34; # 33 bb made of data and 1 flush bucket (unbuffered print)
+ # 1 bb with EOS bucket
+my $sig = join "\n", "received $blocks complete blocks",
+ "filter invoked $invoked times\n";
+my $data = "#" x $blocks . "x" x $blocks;
+my $expected = join "\n", $data, $sig;
+
+{
+ # test the filtering of the mod_perl response handler
+ my $location = '/TestFilter__out_bbs_ctx';
+ my $response = GET_BODY $location;
+ ok t_cmp($response, $expected, "context filter");
+}
diff --git a/2_0_13/t/filter/out_bbs_filebucket.t b/2_0_13/t/filter/out_bbs_filebucket.t
new file mode 100644
index 0000000..53cd409
--- /dev/null
+++ b/2_0_13/t/filter/out_bbs_filebucket.t
@@ -0,0 +1,47 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catdir catfile);
+
+my $url = '/TestFilter__out_bbs_filebucket';
+
+my $dir = catdir Apache::Test::vars('documentroot'), qw(filter);
+
+my @sizes = qw(1 100 500 1000 5000);
+
+plan tests => 2 * scalar @sizes;
+
+for my $size (@sizes) {
+ my ($file, $data) = write_file($size);
+ my $received = GET_BODY "$url?$file";
+
+ my $received_size = length $received;
+ my $expected_size = $size * 1024;
+
+ ok t_cmp length($received), length($data), "length";
+ ok $received && $received eq uc($data);
+ unlink $file;
+}
+
+sub write_file {
+ my $size = shift;
+
+ my $data = "abcd" x ($size * 256);
+
+ my $file = catfile $dir, "data_${size}k.txt";
+ open my $fh, ">$file" or die "can't open $file: $!";
+ # need binmode on Win32 so as not to strip \r, which
+ # are included when sending with sendfile().
+ binmode $fh;
+ print $fh $data;
+ close $fh;
+
+ return ($file, $data);
+}
+
+
diff --git a/2_0_13/t/filter/out_init_basic.t b/2_0_13/t/filter/out_init_basic.t
new file mode 100644
index 0000000..ac879f7
--- /dev/null
+++ b/2_0_13/t/filter/out_init_basic.t
@@ -0,0 +1,18 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $content = "content ok\n";
+my $expected = join '', "init 1\n", "run 1\n", $content, "run 2\n";
+# newer Apache versions may make yet another call, so you will see
+# "run 3\n" as well.
+
+my $location = '/TestFilter__out_init_basic';
+my $response = POST_BODY $location, content => $content;
+ok t_cmp($response, qr/^$expected/, "test filter init functionality");
diff --git a/2_0_13/t/filter/out_str_buffer.t b/2_0_13/t/filter/out_str_buffer.t
new file mode 100644
index 0000000..1b48c82
--- /dev/null
+++ b/2_0_13/t/filter/out_str_buffer.t
@@ -0,0 +1,23 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 2;
+
+my $sep = "-0-";
+my $data = join $sep, "aa" .. "zz";
+
+(my $expected = $data) =~ s/$sep//g;
+my $expected_len = length $expected;
+
+my $location = '/TestFilter__out_str_buffer';
+my $res = POST $location, content => $data;
+#t_debug $res->as_string;
+my $received_len = $res->header('Content-Length') || 0;
+ok t_cmp $received_len, $expected_len, "Content-Length header";
+ok t_cmp $res->content, $expected, "filtered data";
+
diff --git a/2_0_13/t/filter/out_str_ctx.t b/2_0_13/t/filter/out_str_ctx.t
new file mode 100644
index 0000000..4f1f44b
--- /dev/null
+++ b/2_0_13/t/filter/out_str_ctx.t
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $blocks = 33;
+my $invoked = 67; # 33 bb made of data and 1 flush bucket (unbuffered print)
+ # 33 bb made of 1 flush bucket (rflush)
+ # 1 bb with EOS bucket
+my $sig = join "\n", "received $blocks complete blocks",
+ "filter invoked $invoked times\n";
+my $data = "#" x $blocks . "x" x $blocks;
+my $expected = join "\n", $data, $sig;
+
+{
+ # test the filtering of the mod_perl response handler
+ my $location = '/TestFilter__out_str_ctx';
+ my $response = GET_BODY $location;
+ ok t_cmp($response, $expected, "context stream filter");
+}
diff --git a/2_0_13/t/filter/out_str_declined.t b/2_0_13/t/filter/out_str_declined.t
new file mode 100644
index 0000000..488cadd
--- /dev/null
+++ b/2_0_13/t/filter/out_str_declined.t
@@ -0,0 +1,16 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $expected = 11; # 10 flushes and 1 EOS bb
+
+my $location = '/TestFilter__out_str_declined';
+my $response = GET_BODY $location;
+ok t_cmp($response, $expected, "an output filter handler returning DECLINED");
+
diff --git a/2_0_13/t/filter/out_str_lc.t b/2_0_13/t/filter/out_str_lc.t
new file mode 100644
index 0000000..710c2e5
--- /dev/null
+++ b/2_0_13/t/filter/out_str_lc.t
@@ -0,0 +1,14 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 1, need 'mod_alias';
+
+my $location = "/top_dir/Makefile";
+
+my $str = GET_BODY $location;
+
+ok $str !~ /[A-Z]/;
diff --git a/2_0_13/t/filter/out_str_remove.t b/2_0_13/t/filter/out_str_remove.t
new file mode 100644
index 0000000..0740136
--- /dev/null
+++ b/2_0_13/t/filter/out_str_remove.t
@@ -0,0 +1,15 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $expected = "F_O_O_b_a_r_";
+my $location = '/TestFilter__out_str_remove';
+my $response = GET_BODY $location;
+ok t_cmp($response, $expected, "a filter that removes itself");
+
diff --git a/2_0_13/t/filter/out_str_req_eos.t b/2_0_13/t/filter/out_str_req_eos.t
new file mode 100644
index 0000000..3e09ee1
--- /dev/null
+++ b/2_0_13/t/filter/out_str_req_eos.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1, ['include'];
+
+my $location = '/TestFilter__out_str_req_eos';
+
+my $content = 'BODY';
+my $prefix = 'PREFIX_';
+my $suffix = '_SUFFIX';
+
+my $expected = join '', $prefix, $content, $suffix;
+my $received = POST_BODY $location, content => $content;
+
+ok t_cmp($received, $expected,
+ "testing the EOS bucket forwarding through the mp filters chains");
diff --git a/2_0_13/t/filter/out_str_req_mix.t b/2_0_13/t/filter/out_str_req_mix.t
new file mode 100644
index 0000000..d7d839d
--- /dev/null
+++ b/2_0_13/t/filter/out_str_req_mix.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1, ['include'];
+
+my $location = '/TestFilter__out_str_req_mix';
+
+my $content = '<!--#include virtual="/includes/REMOVEclear.shtml" -->';
+
+my $expected = 'This is a clear text';
+my $received = POST_BODY $location, content => $content;
+$received =~ s{\r?\n$}{};
+
+ok t_cmp($expected, $received,
+ "mixing output httpd and mod_perl filters, while preserving order");
diff --git a/2_0_13/t/filter/out_str_reverse.t b/2_0_13/t/filter/out_str_reverse.t
new file mode 100644
index 0000000..8513dac
--- /dev/null
+++ b/2_0_13/t/filter/out_str_reverse.t
@@ -0,0 +1,32 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 2;
+
+my @data = (join('', 'a'..'z'), join('', 0..9));
+
+my $reversed_data = join '', map { scalar(reverse $_) . "\n" } @data;
+my $normal_data = join '', map { $_ . "\n" } @data;
+#t_debug($reversed_data);
+my $sig = "Reversed by mod_perl 2.0\n";
+my $expected = $normal_data . $sig;
+
+{
+ # test the filtering of the mod_perl response handler
+ my $location = '/TestFilter__out_str_reverse';
+ my $response = POST_BODY $location, content => $reversed_data;
+ ok t_cmp($response, $expected, "reverse filter");
+}
+
+{
+ # test the filtering of the non-mod_perl response handler (file)
+ my $location = '/filter/reverse.txt';
+ my $response = GET_BODY $location;
+ $response =~ s/\r//g;
+ ok t_cmp($response, $expected, "reverse filter");
+}
diff --git a/2_0_13/t/filter/out_str_subreq_default.t b/2_0_13/t/filter/out_str_subreq_default.t
new file mode 100644
index 0000000..1f408e5
--- /dev/null
+++ b/2_0_13/t/filter/out_str_subreq_default.t
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache::TestConfig ();
+
+plan tests => 1, need 'mod_alias';
+
+my $location = '/TestFilter__out_str_subreq_default';
+
+my $content1 = "content\n";
+my $content2 = "more content\n";
+my $filter = "filter\n";
+my $subrequest = "default-handler subrequest\n";
+
+my $expected = join '', $content1, $subrequest, $content2, $filter;
+my $received = GET_BODY $location;
+# Win32 and Cygwin fix for line endings
+$received =~ s{\r}{}g if Apache::TestConfig::WIN32 || Apache::TestConfig::CYGWIN;
+
+ok t_cmp($received, $expected,
+ "testing filter-originated lookup_uri() call to core served URI");
diff --git a/2_0_13/t/filter/out_str_subreq_modperl.t b/2_0_13/t/filter/out_str_subreq_modperl.t
new file mode 100644
index 0000000..9b1a875
--- /dev/null
+++ b/2_0_13/t/filter/out_str_subreq_modperl.t
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $location = '/TestFilter__out_str_subreq_modperl';
+
+my $content1 = "content\n";
+my $content2 = "more content\n";
+my $filter = "filter\n";
+my $subrequest = "modperl subrequest\n";
+
+my $expected = join '', $content1, $subrequest, $content2, $filter;
+my $received = GET_BODY $location;
+
+ok t_cmp($received, $expected,
+ "testing filter-originated lookup_uri() call to modperl-served URI");
diff --git a/2_0_13/t/filter/with_subrequest.t b/2_0_13/t/filter/with_subrequest.t
new file mode 100644
index 0000000..d935316
--- /dev/null
+++ b/2_0_13/t/filter/with_subrequest.t
@@ -0,0 +1,13 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 1, need 'mod_alias';
+
+my $location = "/with_subrequest/Makefile";
+
+my $str = GET_BODY $location;
+
+ok $str !~ /[A-Z]/;
diff --git a/2_0_13/t/hooks/TestHooks/access.pm b/2_0_13/t/hooks/TestHooks/access.pm
new file mode 100644
index 0000000..e78c974
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/access.pm
@@ -0,0 +1,50 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::access;
+
+# demonstrates the phases execution (sometimes users claim that
+# PerlInitHandler is running more than once
+# run with:
+# t/TEST -trace=debug -v hooks/access
+
+use strict;
+use warnings FATAL => 'all';
+
+use APR::Table ();
+use Apache2::Access ();
+use Apache2::RequestRec ();
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK FORBIDDEN);
+
+my $allowed_ips = qr{^(10|127)\.};
+
+sub handler {
+ my $r = shift;
+
+ my $fake_ip = $r->headers_in->get('X-Forwarded-For') || "";
+
+ debug "access: " . ($fake_ip =~ $allowed_ips ? "OK\n" : "FORBIDDEN\n");
+
+ return Apache2::Const::FORBIDDEN unless $fake_ip =~ $allowed_ips;
+
+ Apache2::Const::OK;
+}
+
+sub fixup { debug "fixup\n"; Apache2::Const::OK }
+sub init { debug "init\n"; Apache2::Const::OK }
+
+1;
+__DATA__
+<NoAutoConfig>
+PerlModule TestHooks::access
+<Location /TestHooks__access>
+ PerlAccessHandler TestHooks::access
+ PerlInitHandler TestHooks::access::init
+ PerlFixupHandler TestHooks::access::fixup
+ PerlResponseHandler Apache::TestHandler::ok1
+ SetHandler modperl
+</Location>
+#<Location />
+# PerlAccessHandler TestHooks::access
+#</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/authen_basic.pm b/2_0_13/t/hooks/TestHooks/authen_basic.pm
new file mode 100644
index 0000000..a7ba01e
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/authen_basic.pm
@@ -0,0 +1,51 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::authen_basic;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Access ();
+
+use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR);
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+sub handler {
+ my $r = shift;
+
+ my ($rc, $sent_pw) = $r->get_basic_auth_pw;
+
+ return $rc if $rc != Apache2::Const::OK;
+
+ my $user = $r->user;
+
+ # We don't have to check for valid-user in 2.4.0+. If there is bug
+ # in require valid-user handling, it will result in failed test with
+ # bad username/password.
+ if (!APACHE24) {
+ my $requirement = $r->requires->[0]->{requirement};
+ return Apache2::Const::SERVER_ERROR unless $requirement eq 'valid-user';
+ }
+
+ unless ($user eq 'dougm' and $sent_pw eq 'foo') {
+ $r->note_basic_auth_failure;
+ return Apache2::Const::HTTP_UNAUTHORIZED;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<Location /TestHooks__authen_basic>
+ require valid-user
+ AuthType Basic
+ AuthName simple
+ PerlAuthenHandler TestHooks::authen_basic
+ PerlResponseHandler Apache::TestHandler::ok1
+ SetHandler modperl
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/authen_digest.pm b/2_0_13/t/hooks/TestHooks/authen_digest.pm
new file mode 100644
index 0000000..9ccc396
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/authen_digest.pm
@@ -0,0 +1,43 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::authen_digest;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Access ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED);
+
+sub handler {
+
+ my $r = shift;
+
+ # we don't need to do the entire Digest auth round
+ # trip just to see if note_digest_auth_failure is
+ # functioning properly - see authen_digest.t for the
+ # header checks
+ if ($r->args) {
+ $r->note_digest_auth_failure;
+ return Apache2::Const::HTTP_UNAUTHORIZED;
+ }
+
+ $r->user("user");
+ $r->ap_auth_type("Digest");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<Location /TestHooks__authen_digest>
+ PerlAuthenHandler TestHooks::authen_digest
+ PerlResponseHandler Apache::TestHandler::ok
+ SetHandler modperl
+
+ require valid-user
+ AuthType Digest
+ AuthName "Simple Digest"
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/authz.pm b/2_0_13/t/hooks/TestHooks/authz.pm
new file mode 100644
index 0000000..1134eb3
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/authz.pm
@@ -0,0 +1,48 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::authz;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Access ();
+
+use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED);
+
+sub auth_any {
+ my $self = shift;
+ my $r = shift;
+
+ my ($res, $sent_pw) = $r->get_basic_auth_pw;
+ return $res if $res != Apache2::Const::OK;
+
+ unless($r->user and $sent_pw) {
+ # testing $r->note_auth_failure:
+ # AuthType Basic + note_auth_failure == note_basic_auth_failure;
+ $r->note_auth_failure;
+ return Apache2::Const::HTTP_UNAUTHORIZED;
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ my $user = $r->user;
+
+ return Apache2::Const::HTTP_UNAUTHORIZED unless $user;
+
+ return Apache2::Const::HTTP_UNAUTHORIZED unless "dougm" eq $user;
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+require user dougm
+AuthType Basic
+AuthName simple
+PerlModule TestHooks::authz
+PerlAuthenHandler TestHooks::authz->auth_any
+PerlResponseHandler Apache::TestHandler::ok1
+SetHandler modperl
diff --git a/2_0_13/t/hooks/TestHooks/cleanup.pm b/2_0_13/t/hooks/TestHooks/cleanup.pm
new file mode 100644
index 0000000..f493e24
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/cleanup.pm
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::cleanup;
+
+# test various ways to assign cleanup handlers
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use File::Spec::Functions qw(catfile);
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+sub get_file {
+ catfile Apache::Test::vars("documentroot"), "hooks", "cleanup";
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->print('ok');
+ $r->pnotes(items => ["cleanup"," ok"]);
+ $r->push_handlers(PerlCleanupHandler => \&cleanup2);
+
+ return Apache2::Const::OK;
+}
+
+sub cleanup1 {
+ my $r = shift;
+
+ my $items = $r->pnotes('items');
+ die "no items" unless $items;
+ my $item = $items ? $items->[0] : '';
+ #warn "cleanup CALLED\n";
+ t_write_file(get_file(), $item);
+
+ return Apache2::Const::OK;
+}
+
+sub cleanup2 {
+ my $r = shift;
+
+ my $items = $r->pnotes('items');
+ my $item = $items ? $items->[1] : '';
+ #warn "cleanup2 CALLED\n";
+ t_append_file(get_file(), $item);
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__cleanup>
+ SetHandler modperl
+ PerlCleanupHandler TestHooks::cleanup::cleanup1
+ PerlResponseHandler TestHooks::cleanup
+ </Location>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/hooks/TestHooks/cleanup2.pm b/2_0_13/t/hooks/TestHooks/cleanup2.pm
new file mode 100644
index 0000000..1c68dfa
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/cleanup2.pm
@@ -0,0 +1,58 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::cleanup2;
+
+# test the cleanup handler removing a temp file
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use File::Spec::Functions qw(catfile);
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use APR::Pool ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+use APR::Const -compile => 'SUCCESS';
+
+my $file = catfile Apache::Test::config->{vars}->{documentroot},
+ "hooks", "cleanup2";
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ t_write_file($file, "cleanup2 is ok");
+
+ my $status = $r->sendfile($file);
+ die "sendfile has failed" unless $status == APR::Const::SUCCESS;
+
+ $r->pool->cleanup_register(\&cleanup, $file);
+
+ return Apache2::Const::OK;
+}
+
+sub cleanup {
+ my $file_arg = shift;
+
+ debug_sub "called";
+ die "Can't find file: $file_arg" unless -e $file_arg;
+ unlink $file_arg or die "failed to unlink $file_arg";
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__cleanup2>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::cleanup2
+ </Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/error.pm b/2_0_13/t/hooks/TestHooks/error.pm
new file mode 100644
index 0000000..6ce74fd
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/error.pm
@@ -0,0 +1,44 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::error;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+use APR::Table ();
+
+sub handler {
+ my $r = shift;
+ my $args = $r->args();
+ if (defined($args) && $args ne '') {
+ $r->notes->set('error-notes' => $args);
+ }
+ &bomb();
+ Apache2::Const::OK;
+}
+
+sub fail {
+ my $r = shift;
+ $r->print('Error: '.$r->prev->notes->get('error-notes'));
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__error>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::error
+ ErrorDocument 500 /TestHooks__error__fail
+ </Location>
+ <Location /TestHooks__error__fail>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::error::fail
+ </Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/fixup.pm b/2_0_13/t/hooks/TestHooks/fixup.pm
new file mode 100644
index 0000000..80d6fff
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/fixup.pm
@@ -0,0 +1,35 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::fixup;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use APR::Table ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->notes->set(ok => 1);
+
+ Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ ok $r->notes->get('ok');
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlResponseHandler TestHooks::fixup::response
+SetHandler modperl
diff --git a/2_0_13/t/hooks/TestHooks/headerparser.pm b/2_0_13/t/hooks/TestHooks/headerparser.pm
new file mode 100644
index 0000000..780bf78
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/headerparser.pm
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::headerparser;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use APR::Table ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->notes->set(headerparser => 'set');
+
+ Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ ok $r->notes->get('headerparser') eq 'set';
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlOptions +SetupEnv
+PerlResponseHandler TestHooks::headerparser::response
+SetHandler modperl
diff --git a/2_0_13/t/hooks/TestHooks/hookrun.pm b/2_0_13/t/hooks/TestHooks/hookrun.pm
new file mode 100644
index 0000000..c842ee9
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/hookrun.pm
@@ -0,0 +1,156 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::hookrun;
+
+# this test runs all Apache phases from within the very first http
+# phase
+
+# XXX: may be improve the test to do a full-blown test, where each
+# phase does something useful.
+
+# see also TestProtocol::pseudo_http
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::HookRun ();
+use APR::Table ();
+use ModPerl::Util ();
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK DECLINED DONE SERVER_ERROR);
+
+my $path = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+my @phases = qw(
+ PerlPostReadRequestHandler
+ PerlTransHandler
+ PerlMapToStorageHandler
+ PerlHeaderParserHandler
+ PerlAccessHandler
+ PerlAuthenHandler
+ PerlAuthzHandler
+ PerlTypeHandler
+ PerlFixupHandler
+ PerlResponseHandler
+ PerlLogHandler
+);
+
+sub post_read_request {
+ my $r = shift;
+ my $rc;
+
+ $r->push_handlers(PerlTransHandler => \&any);
+ $r->push_handlers(PerlMapToStorageHandler => \&any);
+ $r->push_handlers(PerlHeaderParserHandler => \&any);
+ $r->push_handlers(PerlAccessHandler => \&any);
+ $r->push_handlers(PerlAuthenHandler => \&any);
+ $r->push_handlers(PerlAuthzHandler => \&any);
+ $r->push_handlers(PerlTypeHandler => \&any);
+ $r->push_handlers(PerlFixupHandler => \&any);
+ $r->push_handlers(PerlLogHandler => \&any);
+
+ any($r); # indicate that the post_read_request phase was run
+
+ # for the full Apache logic for running phases starting from
+ # post_read_request and ending with fixup see
+ # ap_process_request_internal in httpd-2.0/server/request.c
+
+ $rc = $r->run_translate_name;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ $rc = $r->run_map_to_storage;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ # this must be run all a big havoc will happen in the following
+ # phases
+ $r->location_merge($path);
+
+ $rc = $r->run_header_parser;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ my $args = $r->args || '';
+ if ($args eq 'die') {
+ $r->die(Apache2::Const::SERVER_ERROR);
+ return Apache2::Const::DONE;
+ }
+
+ $rc = $r->run_access_checker;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ $rc = $r->run_auth_checker;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ $rc = $r->run_check_user_id;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ $rc = $r->run_type_checker;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ $rc = $r->run_fixups;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ # $r->run_handler is called internally by $r->invoke_handler,
+ # invoke_handler sets all kind of filters, and does a few other
+ # things but it's possible to call $r->run_handler, bypassing
+ # invoke_handler
+ $rc = $r->invoke_handler;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ $rc = $r->run_log_transaction;
+ return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED;
+
+ return Apache2::Const::DONE;
+
+ # Apache runs ap_finalize_request_protocol on return of this
+ # handler
+}
+
+sub any {
+ my $r = shift;
+
+ my $callback = ModPerl::Util::current_callback();
+
+ debug "running $callback\n";
+ $r->notes->set($callback => 1);
+
+ # unset the callback that was already run
+ $r->set_handlers($callback => []);
+
+ Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ my @pre_response = (@phases)[0..($#phases-2)];
+ plan tests => scalar(@pre_response);
+
+ for my $phase (@pre_response) {
+ my $note = $r->notes->get($phase);
+ $r->print("$phase:$note\n");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestHooks::hookrun>
+ PerlModule TestHooks::hookrun
+ PerlPostReadRequestHandler TestHooks::hookrun::post_read_request
+ <Location /TestHooks__hookrun>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::hookrun::response
+
+ AuthName modperl
+ AuthType none
+ Require valid-user
+ </Location>
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/init.pm b/2_0_13/t/hooks/TestHooks/init.pm
new file mode 100644
index 0000000..dada6a8
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/init.pm
@@ -0,0 +1,69 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::init;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use APR::Table ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+sub first {
+ my $r = shift;
+
+ $r->notes->set(ok1 => 1);
+
+ Apache2::Const::OK;
+}
+
+sub second {
+ my $r = shift;
+
+ my $ok = $r->notes->get('ok1') || 0;
+
+ $r->notes->set(ok2 => $ok + 1);
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ my $ok = $r->notes->get('ok2') || 0;
+
+ $r->notes->set(ok3 => $ok + 1);
+
+ Apache2::Const::DECLINED;
+}
+
+sub response {
+ my $r = shift;
+
+ my $tests = 3;
+ plan $r, tests => $tests;
+
+ for my $x (1..$tests) {
+ my $val = $r->notes->get("ok$x") || 0;
+ ok $val == $x;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <VirtualHost TestHooks::init>
+ PerlModule TestHooks::init
+ PerlInitHandler TestHooks::init::first
+ <Location /TestHooks__init>
+ PerlInitHandler TestHooks::init::second
+ PerlResponseHandler TestHooks::init
+ PerlResponseHandler TestHooks::init::response
+ SetHandler modperl
+ </Location>
+ </VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/inlined_handlers.pm b/2_0_13/t/hooks/TestHooks/inlined_handlers.pm
new file mode 100644
index 0000000..be25837
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/inlined_handlers.pm
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::inlined_handlers;
+
+# this test exercises httpd.conf inlined one-liner handlers, like:
+# PerlFixupHandler 'sub { use Apache2::Const qw(DECLINED); DECLINED }'
+# previously there was a bug in non-ithreaded-perl implementation
+# where the cached compiled CODE ref didn't have the reference count
+# right.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->print('ok');
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__inlined_handlers>
+ SetHandler modperl
+ PerlFixupHandler 'sub { use Apache2::Const qw(DECLINED); DECLINED }'
+ PerlResponseHandler TestHooks::inlined_handlers
+ </Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers.pm b/2_0_13/t/hooks/TestHooks/push_handlers.pm
new file mode 100644
index 0000000..2d85f6d
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/push_handlers.pm
@@ -0,0 +1,70 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::push_handlers;
+
+# test various ways to push handlers
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+
+use Apache2::Const -compile => qw(OK DECLINED DONE);
+
+sub handler {
+ my $r = shift;
+
+ $r->handler("modperl");
+
+ $r->push_handlers(PerlResponseHandler => \&coderef);
+ $r->push_handlers(PerlResponseHandler =>
+ \&TestHooks::push_handlers::full_coderef);
+
+ $r->push_handlers(PerlResponseHandler =>
+ [\&coderef1, __PACKAGE__.'::coderef2', \&coderef3]);
+
+ $r->push_handlers(PerlResponseHandler =>
+ sub { return say(shift, "anonymous") });
+
+ $r->push_handlers(PerlResponseHandler =>
+ [sub { return say(shift, "anonymous1") },
+ \&coderef4,
+ sub { return say(shift, "anonymous3") },
+ ]);
+
+ $r->push_handlers(PerlResponseHandler => \&end);
+
+ return Apache2::Const::DECLINED;
+}
+
+sub end { return Apache2::Const::DONE }
+sub say { shift->print(shift,"\n"); return Apache2::Const::DECLINED }
+
+sub conf {
+ # this one is configured from httpd.conf
+ my $r= shift;
+ $r->content_type('text/plain');
+ return say($r, "conf");
+}
+
+sub conf1 { return say(shift, "conf1") }
+sub conf2 { return say(shift, "conf2") }
+sub coderef { return say(shift, "coderef") }
+sub coderef1 { return say(shift, "coderef1") }
+sub coderef2 { return say(shift, "coderef2") }
+sub coderef3 { return say(shift, "coderef3") }
+sub coderef4 { return say(shift, "coderef4") }
+sub full_coderef { return say(shift, "full_coderef") }
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__push_handlers>
+ SetHandler modperl
+ PerlHeaderParserHandler TestHooks::push_handlers
+ PerlResponseHandler TestHooks::push_handlers::conf
+ PerlResponseHandler TestHooks::push_handlers::conf1 TestHooks::push_handlers::conf2
+ </Location>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers_anon.pm b/2_0_13/t/hooks/TestHooks/push_handlers_anon.pm
new file mode 100644
index 0000000..abfd028
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/push_handlers_anon.pm
@@ -0,0 +1,63 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::push_handlers_anon;
+
+# in addition to other anon sub handler tests in push_handlers*, here
+# we test an anon sub added at the server startup. in order not to mess
+# with the rest of the test suite, we run it in its own vhost
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::ServerUtil ();
+use APR::Pool ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+use Apache::Test;
+use Apache::TestUtil;
+
+sub add_note {
+ my $r = shift;
+
+ my $count = $r->notes->get("add_note") || 0;
+ $count++;
+ $r->notes->set("add_note", $count);
+ Apache2::Const::DECLINED;
+}
+
+# PerlFixupHandlers added at the server startup should add 3 notes
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ my $count = $r->notes->get("add_note") || 0;
+ ok t_cmp $count, 3, "$count callbacks";
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+# APACHE_TEST_CONFIG_ORDER 1000
+<VirtualHost TestHooks::push_handlers_anon>
+ PerlModule TestHooks::push_handlers_anon
+ <Perl >
+ my $s = Apache2::PerlSections->server;
+
+ $s->push_handlers(PerlFixupHandler =>
+ sub { &TestHooks::push_handlers_anon::add_note });
+ $s->push_handlers(PerlFixupHandler =>
+ \&TestHooks::push_handlers_anon::add_note );
+ $s->push_handlers(PerlFixupHandler =>
+ "TestHooks::push_handlers_anon::add_note" );
+ </Perl>
+
+ <Location /TestHooks__push_handlers_anon>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::push_handlers_anon
+ </Location>
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers_blessed.pm b/2_0_13/t/hooks/TestHooks/push_handlers_blessed.pm
new file mode 100644
index 0000000..0a5dd53
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/push_handlers_blessed.pm
@@ -0,0 +1,45 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::push_handlers_blessed;
+
+# test that we
+# - can push and execute blessed anon handlers
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ my $sub = sub {
+ ok 1;
+
+ return Apache2::Const::OK;
+ };
+
+ my $handler = bless $sub, __PACKAGE__;
+
+ $r->push_handlers(PerlResponseHandler => $handler);
+
+ return Apache2::Const::DECLINED;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<Location /TestHooks__push_handlers_blessed>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::push_handlers_blessed
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers_same_phase.pm b/2_0_13/t/hooks/TestHooks/push_handlers_same_phase.pm
new file mode 100644
index 0000000..6584e12
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/push_handlers_same_phase.pm
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::push_handlers_same_phase;
+
+# test that we
+# - can push handlers into the same phase that is currently running
+# - cannot switch 'perl-script' to 'modperl' and vice versa once
+# inside the response phase
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+sub handler {
+ my $r = shift;
+
+ my $counter = $r->notes->get('counter') || 0;
+ $r->notes->set(counter => $counter+1);
+
+ $r->push_handlers(PerlResponseHandler => \&real_response);
+
+ return Apache2::Const::DECLINED;
+}
+
+sub real_response {
+ my $r = shift;
+
+ plan $r, tests => 3;
+
+ # test that we don't rerun all the handlers again (it should no
+ # longer happen as we don't allow switching 'perl-script' <=>
+ # 'modperl' on the go, but test anyway)
+ my $counter = $r->notes->get('counter') || 0;
+ ok t_cmp($counter, 1,
+ __PACKAGE__ . "::handler must have been called only once");
+
+ my @handlers = @{ $r->get_handlers('PerlResponseHandler') || []};
+ ok t_cmp(scalar(@handlers),
+ 2,
+ "there should be 2 response handlers");
+
+ # once running inside the response phase it shouldn't be possible
+ # to switch from 'perl-script' to 'modperl' and vice versa
+ eval { $r->handler("perl-script") };
+ ok t_cmp($@, qr/Can't switch from/,
+ "can't switch from 'perl-script' to 'modperl' inside " .
+ "the response phase");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<Location /TestHooks__push_handlers_same_phase>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::push_handlers_same_phase
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/set_handlers.pm b/2_0_13/t/hooks/TestHooks/set_handlers.pm
new file mode 100644
index 0000000..f64dbf1
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/set_handlers.pm
@@ -0,0 +1,46 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::set_handlers;
+
+# test various ways to reset/unset handlers list
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ # the first way to reset the handlers list is to pass undef
+ # access handler phase will be not called for mp
+ $r->set_handlers(PerlAccessHandler => undef);
+
+ # the second way to reset the handlers list is to pass []
+ # fixup must be not executed
+ $r->set_handlers(PerlFixupHandler => \&fixup);
+ $r->set_handlers(PerlFixupHandler => []);
+
+ # normal override
+ $r->set_handlers(PerlResponseHandler => sub { die "not to be called"});
+ $r->set_handlers(PerlResponseHandler => [\&Apache::TestHandler::ok1]);
+ $r->handler("modperl");
+
+ return Apache2::Const::OK;
+}
+
+sub fixup {
+ die "fixup must not be executed";
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__set_handlers>
+ PerlHeaderParserHandler TestHooks::set_handlers
+ </Location>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/hooks/TestHooks/stacked_handlers.pm b/2_0_13/t/hooks/TestHooks/stacked_handlers.pm
new file mode 100644
index 0000000..e74a974
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/stacked_handlers.pm
@@ -0,0 +1,70 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::stacked_handlers;
+
+# this test exercises the execution of the stacked handlers and test
+# whether the execution breaks when something different than OK or
+# DECLINED is returned
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+
+use Apache2::Const -compile => qw(OK DECLINED DONE);
+
+sub handler {
+ my $r = shift;
+
+ $r->handler("modperl");
+ $r->push_handlers(PerlResponseHandler => [\&one, \&two, \&three, \&four]);
+
+ return Apache2::Const::OK;
+}
+
+sub one {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->print("one\n");
+
+ return Apache2::Const::DECLINED;
+}
+
+sub two {
+ my $r = shift;
+
+ $r->print("two\n");
+
+ return Apache2::Const::DECLINED;
+}
+
+sub three {
+ my $r = shift;
+
+ $r->print("three\n");
+
+ return Apache2::Const::DONE;
+}
+
+# this one shouldn't get called, because the handler 'three' has
+# returned DONE
+sub four {
+ my $r = shift;
+
+ $r->print("four\n");
+
+ return Apache2::Const::OK;
+}
+
+
+1;
+__DATA__
+<NoAutoConfig>
+ <Location /TestHooks__stacked_handlers>
+ SetHandler modperl
+ PerlHeaderParserHandler TestHooks::stacked_handlers
+ </Location>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/hooks/TestHooks/stacked_handlers2.pm b/2_0_13/t/hooks/TestHooks/stacked_handlers2.pm
new file mode 100644
index 0000000..25f1ca7
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/stacked_handlers2.pm
@@ -0,0 +1,209 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::stacked_handlers2;
+
+# this test exercises the execution of the stacked handlers
+# connection, translation, authen, authz, type, and response
+# phases should end for the first handler that returns OK
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+
+use ModPerl::Util ();
+
+use APR::Table;
+
+use Apache2::Const -compile => qw(OK DECLINED AUTH_REQUIRED SERVER_ERROR);
+
+sub ok {
+
+ callback(shift);
+
+ return Apache2::Const::OK;
+}
+
+sub ok_authen {
+
+ my $r = shift;
+ callback($r);
+
+ $r->user("user");
+ $r->ap_auth_type("Basic");
+
+ return Apache2::Const::OK;
+}
+
+sub declined {
+
+ callback(shift);
+
+ return Apache2::Const::DECLINED;
+}
+
+sub auth_required {
+
+ callback(shift);
+
+ return Apache2::Const::AUTH_REQUIRED;
+}
+
+sub server_error {
+
+ callback(shift);
+
+ return Apache2::Const::SERVER_ERROR;
+}
+
+sub push_handlers {
+
+ my $r = shift;
+
+ $r->push_handlers(PerlFixupHandler => \&ok);
+
+ callback($r);
+
+ return Apache2::Const::OK;
+}
+
+sub callback {
+
+ my $obj = shift;
+
+ my ($r, $callback);
+
+ if ($obj->isa('Apache2::Filter')) {
+ $r = $obj->r;
+ $callback = 'PerlOutputFilterHandler';
+ }
+ else {
+ $r = $obj
+ }
+
+ $callback ||= ModPerl::Util::current_callback;
+
+ my $count = $r->notes->get($callback) || 0;
+
+ $r->notes->set($callback, ++$count);
+}
+
+sub handler {
+
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ callback($r);
+
+ foreach my $callback (qw(PerlPostReadRequestHandler
+ PerlTransHandler
+ PerlMapToStorageHandler
+ PerlHeaderParserHandler
+ PerlAccessHandler
+ PerlAuthenHandler
+ PerlAuthzHandler
+ PerlTypeHandler
+ PerlFixupHandler
+ PerlResponseHandler)) {
+
+ my $count = $r->notes->get($callback) || 0;
+
+ $r->print("ran $count $callback handlers\n");
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub passthru {
+ my $filter = shift;
+
+ unless ($filter->ctx) {
+ callback($filter);
+ $filter->ctx({seen => 1});
+ }
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print($buffer);
+ }
+
+ # this should be ignored?
+ Apache2::Const::OK;
+}
+
+sub filter {
+ my $filter = shift;
+
+ unless ($filter->ctx) {
+ callback($filter);
+ $filter->ctx({seen => 1});
+ }
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print($buffer);
+ }
+
+ if ($filter->seen_eos) {
+ my $count = $filter->r->notes->get('PerlOutputFilterHandler') || 0;
+
+ $filter->print("ran $count PerlOutputFilterHandler handlers\n");
+ }
+
+ # this should be ignored?
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+# create a new virtual host so we can test (almost all) all the hooks
+<NoAutoConfig>
+<VirtualHost TestHooks::stacked_handlers2>
+
+ PerlModule TestHooks::stacked_handlers2
+
+ # all 2 run
+ PerlPostReadRequestHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok
+
+ # 1 run, 1 left behind
+ PerlTransHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::server_error
+
+ # 1 run, 1 left behind
+ PerlMapToStorageHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::server_error
+
+ <Location /TestHooks__stacked_handlers2>
+ # all 4 run
+ PerlHeaderParserHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::declined
+ PerlHeaderParserHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2::ok
+
+ # all 2 run
+ PerlAccessHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok
+
+ # 2 run, 1 left behind
+ PerlAuthenHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2::ok_authen
+ PerlAuthenHandler TestHooks::stacked_handlers2::auth_required
+
+ # 2 run, 1 left behind
+ PerlAuthzHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2::ok
+ PerlAuthzHandler TestHooks::stacked_handlers2::auth_required
+
+ # 1 run, 1 left behind
+ PerlTypeHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers3::server_error
+
+ # all 4 run
+ PerlFixupHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok
+ PerlFixupHandler TestHooks::stacked_handlers2::push_handlers
+
+ # 2 run, 2 left behind
+ PerlResponseHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2
+ PerlResponseHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::server_error
+
+ SetHandler modperl
+ AuthType Basic
+ Require valid-user
+
+ PerlOutputFilterHandler TestHooks::stacked_handlers2::passthru TestHooks::stacked_handlers2::filter
+ </Location>
+
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/startup.pm b/2_0_13/t/hooks/TestHooks/startup.pm
new file mode 100644
index 0000000..ecceeba
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/startup.pm
@@ -0,0 +1,135 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::startup;
+
+# test PerlPostConfigHandler and PerlOpenLogsHandler phases
+# also test that we can run things on vhost entries from these phases
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+use Apache::TestTrace;
+
+use APR::Table;
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use File::Spec::Functions qw(catfile catdir);
+use File::Path qw(mkpath);
+
+use Apache2::Const -compile => 'OK';
+
+my $dir = catdir Apache::Test::vars("documentroot"), 'hooks', 'startup';
+
+sub open_logs {
+ my ($conf_pool, $log_pool, $temp_pool, $s) = @_;
+
+ # main server
+ run("open_logs", $s);
+
+ for (my $vhost_s = $s->next; $vhost_s; $vhost_s = $vhost_s->next) {
+ my $port = $vhost_s->port;
+ my $val = $vhost_s->dir_config->{PostConfig};
+ # we have one vhost that we want to run open_logs for
+ next unless $val && $val eq 'VHost';
+ run("open_logs", $vhost_s);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub post_config {
+ my ($conf_pool, $log_pool, $temp_pool, $s) = @_;
+
+ # main server
+ run("post_config", $s);
+
+ for (my $vhost_s = $s->next; $vhost_s; $vhost_s = $vhost_s->next) {
+ my $port = $vhost_s->port;
+ my $val = $vhost_s->dir_config->{PostConfig};
+ # we have one vhost that we want to run post_config for
+ next unless $val && $val eq 'VHost';
+ run("post_config", $vhost_s);
+ }
+
+ Apache2::Const::OK;
+}
+
+sub run {
+ my ($phase, $s) = @_;
+
+ my $val = $s->dir_config->{PostConfig} or die "Can't read PostConfig var";
+
+ # make sure that these are set at the earliest possible time
+ die '$ENV{MOD_PERL} not set!' unless $ENV{MOD_PERL};
+ die '$ENV{MOD_PERL_API_VERSION} not set!'
+ unless $ENV{MOD_PERL_API_VERSION} == 2;
+
+ my $port = $s->port;
+ my $file = catfile $dir, "$phase-$port";
+
+ mkpath $dir, 0, 0755;
+ open my $fh, ">$file" or die "can't open $file: $!";
+ print $fh $val;
+ close $fh;
+
+ debug "Phase $phase is completed for server at port $port";
+}
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $expected = $s->dir_config->{PostConfig}
+ or die "Can't read PostConfig var";
+ my $port = $s->port;
+
+ for my $phase (qw(open_logs post_config)) {
+ my $file = catfile $dir, "$phase-$port";
+ open my $fh, "$file" or die "can't open $file: $!";
+ my $received = <$fh> || '';
+ close $fh;
+
+ # can't cleanup the file here, because t/SMOKE may run this
+ # test more than once, so we cleanup on startup in modperl_extra.pl
+ # unlink $file;
+
+ if ($expected eq $received) {
+ $r->print("$phase ok\n");
+ } else {
+ warn "phase: $phase\n";
+ warn "port: $port\n";
+ warn "expected: $expected\n";
+ warn "received: $received\n";
+ }
+ }
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<VirtualHost TestHooks::startup>
+ PerlSetVar PostConfig VHost
+ PerlModule TestHooks::startup
+ PerlPostConfigHandler TestHooks::startup::post_config
+ PerlOpenLogsHandler TestHooks::startup::open_logs
+ <Location /TestHooks__startup>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::startup
+ </Location>
+</VirtualHost>
+PerlSetVar PostConfig Main
+PerlModule TestHooks::startup
+PerlPostConfigHandler TestHooks::startup::post_config
+PerlOpenLogsHandler TestHooks::startup::open_logs
+<Location /TestHooks__startup>
+ SetHandler modperl
+ PerlResponseHandler TestHooks::startup
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/trans.pm b/2_0_13/t/hooks/TestHooks/trans.pm
new file mode 100644
index 0000000..279fd5c
--- /dev/null
+++ b/2_0_13/t/hooks/TestHooks/trans.pm
@@ -0,0 +1,49 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestHooks::trans;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestConfig ();
+
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+my %trans = (
+ '/TestHooks/trans.pm' => sub {
+ my $r = shift;
+ $r->filename(__FILE__);
+ Apache2::Const::OK;
+ },
+ '/phooey' => sub {
+ my $r = shift;
+ $r->filename(__FILE__); #filename is currently required
+ $r->uri('/TestHooks::trans');
+ Apache2::Const::OK;
+ },
+);
+
+sub handler {
+ my $r = shift;
+
+ my $uri = $r->uri;
+
+ my $handler = $trans{ $uri };
+
+ return Apache2::Const::DECLINED unless $handler;
+
+ $handler->($r);
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+ <VirtualHost TestHooks::trans>
+ PerlTransHandler TestHooks::trans
+ <Location /TestHooks__trans>
+ PerlResponseHandler Apache::TestHandler::ok1
+ SetHandler modperl
+ </Location>
+ </VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/hooks/access.t b/2_0_13/t/hooks/access.t
new file mode 100644
index 0000000..3266a3c
--- /dev/null
+++ b/2_0_13/t/hooks/access.t
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 4, need 'HTML::HeadParser';
+
+my $location = "/TestHooks__access";
+
+ok ! GET_OK $location;
+
+my $rc = GET_RC $location;
+
+ok $rc == 403;
+
+ok GET_OK $location, 'X-Forwarded-For' => '127.0.0.1';
+
+ok ! GET_OK $location, 'X-Forwarded-For' => '666.0.0.1';
+
+
diff --git a/2_0_13/t/hooks/authen_basic.t b/2_0_13/t/hooks/authen_basic.t
new file mode 100644
index 0000000..759d010
--- /dev/null
+++ b/2_0_13/t/hooks/authen_basic.t
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 4, need need_lwp, need_auth, 'HTML::HeadParser';
+
+my $location = "/TestHooks__authen_basic";
+
+sok {
+ ! GET_OK $location;
+};
+
+sok {
+ my $rc = GET_RC $location;
+ $rc == 401;
+};
+
+sok {
+ GET_OK $location, username => 'dougm', password => 'foo';
+};
+
+# since LWP 5.815, the user agent retains credentials
+# tell Apache::TestRequest to reinitialize its global agent
+Apache::TestRequest::user_agent(reset => 1);
+
+sok {
+ ! GET_OK $location, username => 'dougm', password => 'wrong';
+};
+
+
+
diff --git a/2_0_13/t/hooks/authen_digest.t b/2_0_13/t/hooks/authen_digest.t
new file mode 100644
index 0000000..3bc9c97
--- /dev/null
+++ b/2_0_13/t/hooks/authen_digest.t
@@ -0,0 +1,52 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 7, need need_lwp, 'auth_digest', 'HTML::HeadParser';
+
+my $location = '/TestHooks__authen_digest';
+
+{
+ my $response = GET $location;
+
+ ok t_cmp($response->code,
+ 200,
+ 'handler returned HTTP_OK');
+
+ my $wwwauth = $response->header('WWW-Authenticate');
+
+ t_debug('response had no WWW-Authenticate header');
+ ok (!$wwwauth);
+}
+
+{
+ my $response = GET "$location?fail";
+
+ ok t_cmp($response->code,
+ 401,
+ 'handler returned HTTP_UNAUTHORIZED');
+
+ my $wwwauth = $response->header('WWW-Authenticate');
+
+ t_debug('response had a WWW-Authenticate header');
+ ok ($wwwauth);
+
+ ok t_cmp($wwwauth,
+ qr/^Digest/,
+ 'response is using Digest authentication scheme');
+
+ ok t_cmp($wwwauth,
+ qr/realm="Simple Digest"/,
+ 'WWW-Authenticate header contains the proper realm');
+
+ ok t_cmp($wwwauth,
+ qr/nonce="/,
+ 'WWW-Authenticate header contains a nonce');
+
+ # other fields, such as qop, are added only if add additional
+ # configuration directives, such as AuthDigestQop
+}
diff --git a/2_0_13/t/hooks/authz.t b/2_0_13/t/hooks/authz.t
new file mode 100644
index 0000000..5ad3b8e
--- /dev/null
+++ b/2_0_13/t/hooks/authz.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 4, need need_lwp, 'HTML::HeadParser';
+
+my $location = "/TestHooks__authz";
+
+ok ! GET_OK $location;
+
+my $rc = GET_RC $location;
+
+ok $rc == 401;
+
+ok GET_OK $location, username => 'dougm', password => 'foo';
+
+# since LWP 5.815, the user agent retains credentials
+# tell Apache::TestRequest to reinitialize its global agent
+Apache::TestRequest::user_agent(reset => 1);
+
+ok ! GET_OK $location, username => 'jobbob', password => 'whatever';
+
+
diff --git a/2_0_13/t/hooks/cleanup.t b/2_0_13/t/hooks/cleanup.t
new file mode 100644
index 0000000..d47554b
--- /dev/null
+++ b/2_0_13/t/hooks/cleanup.t
@@ -0,0 +1,55 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catfile catdir);
+
+use constant SIZE => 10;
+use constant TRIES => 20;
+
+my $file = catfile Apache::Test::vars("documentroot"), "hooks", "cleanup";
+
+plan tests => 2;
+
+{
+ # this registers and performs cleanups, but we test whether the
+ # cleanup was run only in the next sub-test
+ my $location = "/TestHooks__cleanup";
+ my $expected = 'ok';
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "register req cleanup");
+}
+
+{
+ # this sub-tests checks that the cleanup stage was run successfully
+
+ # since Apache destroys the request rec after the logging has been
+ # finished, we have to give it some time to get there
+ # and fill in the file. (wait 0.25 .. 5 sec)
+ my $t = 0;
+ select undef, undef, undef, 0.25
+ until -e $file && -s _ == SIZE || $t++ == TRIES;
+
+ unless (-e $file) {
+ t_debug("can't find $file");
+ ok 0;
+ }
+ else {
+ open my $fh, $file or die "Can't open $file: $!";
+ my $received = <$fh> || '';
+ close $fh;
+ my $expected = "cleanup ok";
+ ok t_cmp($received, $expected, "verify req cleanup execution");
+
+ # XXX: while Apache::TestUtil fails to cleanup by itself
+ unlink $file;
+ }
+
+}
+
+
+
diff --git a/2_0_13/t/hooks/cleanup2.t b/2_0_13/t/hooks/cleanup2.t
new file mode 100644
index 0000000..fcd9e74
--- /dev/null
+++ b/2_0_13/t/hooks/cleanup2.t
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use File::Spec::Functions qw(catfile catdir);
+
+use constant TRIES => 20;
+
+my $vars = Apache::Test::config->{vars};
+my $dir = catdir $vars->{documentroot}, "hooks";
+my $file = catfile $dir, "cleanup2";
+
+plan tests => 2;
+
+{
+ # cleanup, just to make sure we start with virgin state
+ if (-e $file) {
+ unlink $file or die "Couldn't remove $file";
+ }
+ # this registers and performs cleanups, but we test whether the
+ # cleanup was run only in the next sub-test
+ my $location = "/TestHooks__cleanup2";
+ my $expected = 'cleanup2 is ok';
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "register req cleanup");
+}
+
+{
+ # this sub-tests checks that the cleanup stage was run successfully
+ # which is supposed to remove the file that was created
+ #
+ # since Apache destroys the request rec after the logging has been
+ # finished, we have to give it some time to get there
+ # and remove in the file. (wait 0.25 .. 5 sec)
+ my $t = 0;
+ select undef, undef, undef, 0.25 until !-e $file || $t++ == TRIES;
+
+ if (-e $file) {
+ t_debug("$file wasn't removed by the cleanup phase");
+ ok 0;
+ unlink $file; # cleanup
+ }
+ else {
+ ok 1;
+ }
+}
+
+
+
diff --git a/2_0_13/t/hooks/error.t b/2_0_13/t/hooks/error.t
new file mode 100644
index 0000000..160d43a
--- /dev/null
+++ b/2_0_13/t/hooks/error.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 2;
+
+{
+ my $location = "/TestHooks__error";
+ my $expected = qr/^Error: Undefined subroutine/;
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "error-notes set on ErrorDocument");
+}
+
+{
+ my $error_seed_text = 'seed_text';
+ my $location = "/TestHooks__error?$error_seed_text";
+ my $expected = qr/^Error: \Q$error_seed_text\E, Undefined subroutine/;
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "seeded error-notes set on ErrorDocument");
+}
diff --git a/2_0_13/t/hooks/hookrun.t b/2_0_13/t/hooks/hookrun.t
new file mode 100644
index 0000000..d1c44f1
--- /dev/null
+++ b/2_0_13/t/hooks/hookrun.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = 'TestHooks::hookrun';
+my $config = Apache::Test::config();
+my $path = Apache::TestRequest::module2path($module);
+
+Apache::TestRequest::module($module);
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+plan tests => 10;
+
+my $ret = GET "http://$hostport/$path?die";
+ok t_cmp $ret->code, 500, '$r->die';
+
+my $body = GET_BODY_ASSERT "http://$hostport/$path?normal";
+for my $line (split /\n/, $body) {
+ my ($phase, $value) = split /:/, $line;
+ ok t_cmp $value, 1, "$phase";
+}
diff --git a/2_0_13/t/hooks/init.t b/2_0_13/t/hooks/init.t
new file mode 100644
index 0000000..e7355ae
--- /dev/null
+++ b/2_0_13/t/hooks/init.t
@@ -0,0 +1,17 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestHooks::init';
+
+Apache::TestRequest::module($module);
+my $path = Apache::TestRequest::module2path($module);
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/hooks/inlined_handlers.t b/2_0_13/t/hooks/inlined_handlers.t
new file mode 100644
index 0000000..2aa7f6d
--- /dev/null
+++ b/2_0_13/t/hooks/inlined_handlers.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use TestCommon::SameInterp;
+
+plan tests => 2, need 'HTML::HeadParser';
+
+my $location = "/TestHooks__inlined_handlers";
+
+my $expected = "ok";
+for (1..2) {
+ my $received = GET $location;
+
+ ok t_cmp(
+ $received->content,
+ $expected,
+ "anonymous handlers in httpd.conf test",
+ );
+}
+
diff --git a/2_0_13/t/hooks/push_handlers.t b/2_0_13/t/hooks/push_handlers.t
new file mode 100644
index 0000000..c4656b6
--- /dev/null
+++ b/2_0_13/t/hooks/push_handlers.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my @refs = qw(conf conf1 conf2 coderef
+ full_coderef coderef1 coderef2 coderef3);
+my @anon = qw(anonymous anonymous1 coderef4 anonymous3);
+
+my @strings = (@refs, @anon);
+
+my $location = "/TestHooks__push_handlers";
+my $expected = join "\n", @strings, '';
+my $received = GET_BODY $location;
+
+ok t_cmp($received, $expected, "push_handlers ways");
diff --git a/2_0_13/t/hooks/push_handlers_anon.t b/2_0_13/t/hooks/push_handlers_anon.t
new file mode 100644
index 0000000..5c39d92
--- /dev/null
+++ b/2_0_13/t/hooks/push_handlers_anon.t
@@ -0,0 +1,12 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# the handler is configured in modperl_extra.pl via
+# Apache2::ServerUtil->server->add_config
+
+use Apache::TestUtil;
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+my $module = 'TestHooks::push_handlers_anon';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/hooks/stacked_handlers.t b/2_0_13/t/hooks/stacked_handlers.t
new file mode 100644
index 0000000..6d6f242
--- /dev/null
+++ b/2_0_13/t/hooks/stacked_handlers.t
@@ -0,0 +1,15 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1;
+
+my $location = "/TestHooks__stacked_handlers";
+my $expected = join "\n", qw(one two three), '';
+my $received = GET_BODY $location;
+
+ok t_cmp($received, $expected, "stacked_handlers");
diff --git a/2_0_13/t/hooks/stacked_handlers2.t b/2_0_13/t/hooks/stacked_handlers2.t
new file mode 100644
index 0000000..9c29d12
--- /dev/null
+++ b/2_0_13/t/hooks/stacked_handlers2.t
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = "TestHooks::stacked_handlers2";
+Apache::TestRequest::module($module);
+
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+my $path = Apache::TestRequest::module2path($module);
+
+my $location = "http://$hostport/$path";
+
+t_debug("connecting to $location");
+
+plan tests => 1;
+
+my $expected = q!ran 2 PerlPostReadRequestHandler handlers
+ran 1 PerlTransHandler handlers
+ran 1 PerlMapToStorageHandler handlers
+ran 4 PerlHeaderParserHandler handlers
+ran 2 PerlAccessHandler handlers
+ran 2 PerlAuthenHandler handlers
+ran 2 PerlAuthzHandler handlers
+ran 1 PerlTypeHandler handlers
+ran 4 PerlFixupHandler handlers
+ran 2 PerlResponseHandler handlers
+ran 2 PerlOutputFilterHandler handlers!;
+
+chomp(my $received = GET_BODY_ASSERT $location);
+
+ok t_cmp($received, $expected, "stacked_handlers");
diff --git a/2_0_13/t/hooks/startup.t b/2_0_13/t/hooks/startup.t
new file mode 100644
index 0000000..7e2c218
--- /dev/null
+++ b/2_0_13/t/hooks/startup.t
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $config = Apache::Test::config();
+my $path = Apache::TestRequest::module2path('TestHooks::startup');
+
+my @modules = qw(default TestHooks::startup);
+
+plan tests => scalar @modules;
+
+my $expected = join '', "open_logs ok\n", "post_config ok\n";
+
+for my $module (sort @modules) {
+
+ Apache::TestRequest::module($module);
+ my $hostport = Apache::TestRequest::hostport($config);
+ t_debug("connecting to $hostport");
+
+ ok t_cmp(GET_BODY_ASSERT("http://$hostport/$path"),
+ $expected,
+ "testing PostConfig");
+}
+
diff --git a/2_0_13/t/hooks/trans.t b/2_0_13/t/hooks/trans.t
new file mode 100644
index 0000000..95b21e9
--- /dev/null
+++ b/2_0_13/t/hooks/trans.t
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use Apache2::Const ':common';
+
+my $module = 'TestHooks::trans';
+Apache::TestRequest::module($module);
+my $path = Apache::TestRequest::module2path($module);
+my $config = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+t_debug("connecting to $hostport");
+
+plan tests => 3, need 'HTML::HeadParser';
+
+t_client_log_error_is_expected();
+ok t_cmp GET_RC("http://$hostport/nope"), NOT_FOUND;
+
+my $body = GET_BODY "http://$hostport/TestHooks/trans.pm";
+
+ok $body =~ /package $module/;
+
+ok GET_OK "http://$hostport/phooey";
diff --git a/2_0_13/t/htdocs/TestAPI__add_config/htaccess b/2_0_13/t/htdocs/TestAPI__add_config/htaccess
new file mode 100644
index 0000000..cd9bed1
--- /dev/null
+++ b/2_0_13/t/htdocs/TestAPI__add_config/htaccess
@@ -0,0 +1 @@
+TestAddConfig Htaccess
diff --git a/2_0_13/t/htdocs/api/auth-groups b/2_0_13/t/htdocs/api/auth-groups
new file mode 100644
index 0000000..90f5994
--- /dev/null
+++ b/2_0_13/t/htdocs/api/auth-groups
@@ -0,0 +1,2 @@
+bar: goo bar
+tar: mar far
diff --git a/2_0_13/t/htdocs/api/auth-users b/2_0_13/t/htdocs/api/auth-users
new file mode 100644
index 0000000..272a21b
--- /dev/null
+++ b/2_0_13/t/htdocs/api/auth-users
@@ -0,0 +1,2 @@
+goo:$apr1$g.mxW/..$p8ILT9D4345OO6vtYt8mT0
+bar:$apr1$ALRiO/..$GxXWAshiDKPmFGUA7r66e/
diff --git a/2_0_13/t/htdocs/api/custom_response.txt b/2_0_13/t/htdocs/api/custom_response.txt
new file mode 100644
index 0000000..f9e84f1
--- /dev/null
+++ b/2_0_13/t/htdocs/api/custom_response.txt
@@ -0,0 +1 @@
+This is a custom file/url response
diff --git a/2_0_13/t/htdocs/api/slurp.pl b/2_0_13/t/htdocs/api/slurp.pl
new file mode 100644
index 0000000..43adae0
--- /dev/null
+++ b/2_0_13/t/htdocs/api/slurp.pl
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+my $z = <<EOI;
+English: Internet
+Hebrew : \x{05D0}\x{05D9}\x{05E0}\x{05D8}\x{05E8}\x{05E0}\x{05D8}
+EOI
+$z;
diff --git a/2_0_13/t/htdocs/filter/reverse.txt b/2_0_13/t/htdocs/filter/reverse.txt
new file mode 100644
index 0000000..7ca9d67
--- /dev/null
+++ b/2_0_13/t/htdocs/filter/reverse.txt
@@ -0,0 +1,2 @@
+zyxwvutsrqponmlkjihgfedcba
+9876543210
diff --git a/2_0_13/t/htdocs/filter/subrequest.txt b/2_0_13/t/htdocs/filter/subrequest.txt
new file mode 100644
index 0000000..93dfba3
--- /dev/null
+++ b/2_0_13/t/htdocs/filter/subrequest.txt
@@ -0,0 +1 @@
+default-handler subrequest
diff --git a/2_0_13/t/htdocs/includes-registry/cgipm.pl b/2_0_13/t/htdocs/includes-registry/cgipm.pl
new file mode 100755
index 0000000..1f2b824
--- /dev/null
+++ b/2_0_13/t/htdocs/includes-registry/cgipm.pl
@@ -0,0 +1,11 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache2::compat ();
+use CGI ();
+
+my $cgi = CGI->new;
+
+print $cgi->header;
+
+print "cgi.pm\n";
+
+__END__
diff --git a/2_0_13/t/htdocs/includes-registry/test.pl b/2_0_13/t/htdocs/includes-registry/test.pl
new file mode 100755
index 0000000..87d29cc
--- /dev/null
+++ b/2_0_13/t/htdocs/includes-registry/test.pl
@@ -0,0 +1,4 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+print "Content-type: text/html\n\n";
+
+print "Hello World<br>\n";
diff --git a/2_0_13/t/htdocs/includes-registry/test.spl b/2_0_13/t/htdocs/includes-registry/test.spl
new file mode 100755
index 0000000..6ce1195
--- /dev/null
+++ b/2_0_13/t/htdocs/includes-registry/test.spl
@@ -0,0 +1,23 @@
+use strict;
+
+#XXX: this test needs to be more robust.
+#various output buffers spread across multiple prints
+#more mod_include features mixed and checking that the output
+#is *exactly* what we expected, not just matching a few patterns.
+
+print "Content-type: text/html\n\n";
+
+my $r = shift;
+
+my $test_string = 'Perl-SSI';
+
+$r->subprocess_env->set(MY_TEST => $test_string);
+
+print <<EOF;
+Hello World from <!--#echo var="SERVER_ADMIN" --><br>
+Local date is <!--#echo var="DATE_LOCAL" --><br>
+Brought to you by <!--#echo var="MY_TEST" -->
+<!--#echo var="SERVER_SOFTWARE" -->
+<br>
+EOF
+
diff --git a/2_0_13/t/htdocs/includes/clear.shtml b/2_0_13/t/htdocs/includes/clear.shtml
new file mode 100644
index 0000000..a636c08
--- /dev/null
+++ b/2_0_13/t/htdocs/includes/clear.shtml
@@ -0,0 +1 @@
+This is a REMOVEclear text
diff --git a/2_0_13/t/htdocs/includes/footer.shtml b/2_0_13/t/htdocs/includes/footer.shtml
new file mode 100644
index 0000000..cc8ce24
--- /dev/null
+++ b/2_0_13/t/htdocs/includes/footer.shtml
@@ -0,0 +1,2 @@
+<hr>
+<h5>footer</h5>
diff --git a/2_0_13/t/htdocs/includes/header.shtml b/2_0_13/t/htdocs/includes/header.shtml
new file mode 100644
index 0000000..f595ab0
--- /dev/null
+++ b/2_0_13/t/htdocs/includes/header.shtml
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title><!--#echo var="QUERY_STRING" --></title>
+<meta http-equiv="Content-Type" content="text/html">
+</head>
+
+<h1><!--#echo var="QUERY_STRING" --></h1>
diff --git a/2_0_13/t/htdocs/includes/test.shtml b/2_0_13/t/htdocs/includes/test.shtml
new file mode 100644
index 0000000..ee62d73
--- /dev/null
+++ b/2_0_13/t/htdocs/includes/test.shtml
@@ -0,0 +1,9 @@
+<!--#include virtual="/includes/header.shtml?mod_perl mod_include test" -->
+
+<!--#include virtual="/includes-registry/test.pl" -->
+
+<!--#include virtual="/includes-registry/cgipm.pl" -->
+
+<p align=right>[<a href="../index.html">back</a>]</p>
+
+<!--#include virtual="/includes/footer.shtml" -->
diff --git a/2_0_13/t/htdocs/merge3/htaccess b/2_0_13/t/htdocs/merge3/htaccess
new file mode 100644
index 0000000..3182b66
--- /dev/null
+++ b/2_0_13/t/htdocs/merge3/htaccess
@@ -0,0 +1,6 @@
+# htaccess file for t/response/TestModperl/merge.pm
+
+PerlSetEnv MergeSetEnv3 SetEnv3Merge3Val
+PerlSetVar MergeSetVar3 SetVar3Merge3Val
+PerlSetVar MergeAddVar3 AddVar3Merge3Val1
+PerlAddVar MergeAddVar3 AddVar3Merge3Val2
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/config_require.pl b/2_0_13/t/htdocs/modperl/setupenv2/config_require.pl
new file mode 100644
index 0000000..c1a7709
--- /dev/null
+++ b/2_0_13/t/htdocs/modperl/setupenv2/config_require.pl
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+TestModperl::setupenv2::register_mixed();
+TestModperl::setupenv2::register_perl();
+$ENV{EnvChangeMixedTest} = "config_require";
+$ENV{EnvChangePerlTest} = "config_require";
+1;
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/module.pm b/2_0_13/t/htdocs/modperl/setupenv2/module.pm
new file mode 100644
index 0000000..df7c5f2
--- /dev/null
+++ b/2_0_13/t/htdocs/modperl/setupenv2/module.pm
@@ -0,0 +1,7 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package htdocs::modperl::setupenv2::module;
+TestModperl::setupenv2::register_mixed();
+TestModperl::setupenv2::register_perl();
+$ENV{EnvChangeMixedTest} = "perlmodule";
+$ENV{EnvChangePerlTest} = "perlmodule";
+1;
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/post_config_require.pl b/2_0_13/t/htdocs/modperl/setupenv2/post_config_require.pl
new file mode 100644
index 0000000..d75fefb
--- /dev/null
+++ b/2_0_13/t/htdocs/modperl/setupenv2/post_config_require.pl
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+TestModperl::setupenv2::register_mixed();
+TestModperl::setupenv2::register_perl();
+$ENV{EnvChangeMixedTest} = "post_config_require";
+$ENV{EnvChangePerlTest} = "post_config_require";
+1;
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/require.pl b/2_0_13/t/htdocs/modperl/setupenv2/require.pl
new file mode 100644
index 0000000..417f471
--- /dev/null
+++ b/2_0_13/t/htdocs/modperl/setupenv2/require.pl
@@ -0,0 +1,6 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+TestModperl::setupenv2::register_mixed();
+TestModperl::setupenv2::register_perl();
+$ENV{EnvChangeMixedTest} = "require";
+$ENV{EnvChangePerlTest} = "require";
+1;
diff --git a/2_0_13/t/htdocs/perlio/MoonRise.jpeg b/2_0_13/t/htdocs/perlio/MoonRise.jpeg
new file mode 100644
index 0000000..5a57b91
--- /dev/null
+++ b/2_0_13/t/htdocs/perlio/MoonRise.jpeg
Binary files differ
diff --git a/2_0_13/t/htdocs/perlio/redrum.txt b/2_0_13/t/htdocs/perlio/redrum.txt
new file mode 100644
index 0000000..e0e634d
--- /dev/null
+++ b/2_0_13/t/htdocs/perlio/redrum.txt
@@ -0,0 +1,8 @@
+ALL wORk and NO play mAKes Jack A dull BoY.
+ALl WORK and no plAy makEs JaCk a dULl boY.
+All wORk AND no PLAy mAkes JACk A DULL boy.
+AlL WORK and nO play MAKES JacK a dUlL bOy.
+ALL wOrK ANd no PLAY makes JACk A dULl Boy.
+All woRk and NO play mAKes Jack a Dull BOY.
+alL work and no pLaY makeS JaCk a dull boy.
+aLL wORK aND nO pLAY mAKES Jack A dULL bOY.
diff --git a/2_0_13/t/htdocs/protocols/basic-auth b/2_0_13/t/htdocs/protocols/basic-auth
new file mode 100644
index 0000000..afb4872
--- /dev/null
+++ b/2_0_13/t/htdocs/protocols/basic-auth
@@ -0,0 +1 @@
+stas:$apr1$qnKIk...$TRSGo5zlwo3LMc0R/iLWo/
diff --git a/2_0_13/t/htdocs/vhost/post_config.pl b/2_0_13/t/htdocs/vhost/post_config.pl
new file mode 100644
index 0000000..472f80f
--- /dev/null
+++ b/2_0_13/t/htdocs/vhost/post_config.pl
@@ -0,0 +1,9 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::ServerUtil ();
+
+$TestVhost::config::restart_count = Apache2::ServerUtil::restart_count();
+
+1;
diff --git a/2_0_13/t/htdocs/vhost/startup.pl b/2_0_13/t/htdocs/vhost/startup.pl
new file mode 100644
index 0000000..ae156e6
--- /dev/null
+++ b/2_0_13/t/htdocs/vhost/startup.pl
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use warnings;
+use strict;
+
+use Apache2::ServerUtil ();
+use Apache2::ServerRec ();
+
+use File::Spec::Functions qw(catdir);
+
+# base server
+# XXX: at the moment this is wrong, since it return the base server $s
+# and not the vhost's one. needs to be fixed.
+my $s = Apache2::ServerUtil->server;
+
+my $vhost_doc_root = catdir Apache2::ServerUtil::server_root, qw(htdocs vhost);
+
+# testing $s->add_config() in vhost
+my $conf = <<"EOC";
+# must use PerlModule here to check for segfaults
+# and that the module is loaded by vhost
+PerlModule TestVhost::config
+PerlSetVar DocumentRootCheck $vhost_doc_root
+<Location /TestVhost__config>
+ SetHandler modperl
+ PerlResponseHandler TestVhost::config::my_handler
+</Location>
+EOC
+
+$s->add_config([split /\n/, $conf]);
+
+# this used to have problems on win32
+$s->add_config(['<Perl >', '1;', '</Perl>']);
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/base64.pm b/2_0_13/t/lib/TestAPRlib/base64.pm
new file mode 100644
index 0000000..1867a4a
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/base64.pm
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::base64;
+
+# testing APR::Base64 API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Base64;
+
+sub num_of_tests {
+ return 3;
+}
+
+sub test {
+
+ my $str = '12345qwert!@#$%';
+ my $encoded = APR::Base64::encode($str);
+
+ t_debug("encoded string: $encoded");
+ ok t_cmp($encoded, 'MTIzNDVxd2VydCFAIyQl', 'encode');
+
+ ok t_cmp(APR::Base64::encode_len(length $str),
+ length $encoded,
+ "encoded length");
+
+ ok t_cmp(APR::Base64::decode($encoded), $str, "decode");
+
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/brigade.pm b/2_0_13/t/lib/TestAPRlib/brigade.pm
new file mode 100644
index 0000000..5fdcc4c
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/brigade.pm
@@ -0,0 +1,107 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::brigade;
+
+# testing APR::Brigade in this tests.
+# Other tests do that too:
+# TestAPR::flatten : flatten()
+# TestAPR::bucket : is_empty(), first(), last()
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Pool ();
+use APR::Brigade ();
+use APR::Bucket ();
+use APR::BucketAlloc ();
+
+use Apache2::Const -compile => 'OK';
+
+sub num_of_tests {
+ return 14;
+}
+
+sub test {
+
+ my $p = APR::Pool->new();
+ my $ba = APR::BucketAlloc->new($p);
+
+ # basic + pool + destroy
+ {
+ my $bb = APR::Brigade->new($p, $ba);
+
+ t_debug('$bb is defined');
+ ok defined $bb;
+
+ t_debug('$bb ISA APR::Brigade object');
+ ok $bb->isa('APR::Brigade');
+
+ my $pool = $bb->pool;
+
+ t_debug('$pool is defined');
+ ok defined $pool;
+
+ t_debug('$pool ISA APR::Pool object');
+ ok $pool->isa('APR::Pool');
+
+ t_debug("destroy");
+ $bb->destroy;
+ ok 1;
+ }
+
+ # concat / split / length / flatten
+ {
+ my $bb1 = APR::Brigade->new($p, $ba);
+ $bb1->insert_head(APR::Bucket->new($ba, "11"));
+ $bb1->insert_tail(APR::Bucket->new($ba, "12"));
+
+ my $bb2 = APR::Brigade->new($p, $ba);
+ $bb2->insert_head(APR::Bucket->new($ba, "21"));
+ $bb2->insert_tail(APR::Bucket->new($ba, "22"));
+
+ # concat
+ $bb1->concat($bb2);
+ # bb1: 11, 12, 21, 22
+ ok t_cmp($bb1->length, 8, "total data length in bb");
+ my $len = $bb1->flatten(my $data);
+ ok t_cmp($len, 8, "bb flatten/len");
+ ok t_cmp($data, "11122122", "bb flatten/data");
+ t_debug('$bb2 is empty');
+ ok $bb2->is_empty;
+
+ # split
+ my $b = $bb1->first; # 11
+ $b = $bb1->next($b); # 12
+ my $bb3 = $bb1->split($b);
+
+ # bb1: 11, bb3: 12, 21, 22
+ $len = $bb1->flatten($data);
+ ok t_cmp($len, 2, "bb1 flatten/len");
+ ok t_cmp($data, "11", "bb1 flatten/data");
+ $len = $bb3->flatten($data);
+ ok t_cmp($len, 6, "bb3 flatten/len");
+ ok t_cmp($data, "122122", "bb3 flatten/data");
+ }
+
+ # out-of-scope pools
+ {
+ my $bb1 = APR::Brigade->new(APR::Pool->new, $ba);
+ $bb1->insert_head(APR::Bucket->new($ba, "11"));
+ $bb1->insert_tail(APR::Bucket->new($ba, "12"));
+
+ # try to overwrite the temp pool data
+ require APR::Table;
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+ # now test that we are still OK
+
+ my $len = $bb1->flatten(my $data);
+ ok t_cmp($data, "1112", "correct data");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/bucket.pm b/2_0_13/t/lib/TestAPRlib/bucket.pm
new file mode 100644
index 0000000..2e9b542
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/bucket.pm
@@ -0,0 +1,211 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::bucket;
+
+# a mix of APR::Bucket and APR::BucketType tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use TestCommon::Utils;
+
+use APR::Pool ();
+use APR::Bucket ();
+use APR::BucketAlloc ();
+use APR::BucketType ();
+use APR::Table ();
+
+use APR::Const -compile => 'SUCCESS';
+
+sub num_of_tests {
+ return 21;
+}
+
+sub test {
+
+ my $pool = APR::Pool->new();
+ my $ba = APR::BucketAlloc->new($pool);
+
+ # new: basic
+ {
+ my $data = "foobar";
+ my $b = APR::Bucket->new($ba, $data);
+
+ t_debug('$b is defined');
+ ok defined $b;
+
+ t_debug('$b ISA APR::Bucket object');
+ ok $b->isa('APR::Bucket');
+
+ my $type = $b->type;
+ ok t_cmp $type->name, 'mod_perl SV bucket', "type";
+
+ ok t_cmp $b->length, length($data), "modperl b->length";
+ }
+
+ # new: offset
+ {
+ my $data = "foobartar";
+ my $offset = 3;
+ my $real = substr $data, $offset;
+ my $b = APR::Bucket->new($ba, $data, $offset);
+ my $rlen = $b->read(my $read);
+ ok t_cmp $read, $real, 'new($data, $offset)/buffer';
+ ok t_cmp $rlen, length($read), 'new($data, $offset)/len';
+ ok t_cmp $b->start, $offset, 'offset';
+
+ }
+
+ # new: offset+len
+ {
+ my $data = "foobartar";
+ my $offset = 3;
+ my $len = 3;
+ my $real = substr $data, $offset, $len;
+ my $b = APR::Bucket->new($ba, $data, $offset, $len);
+ my $rlen = $b->read(my $read);
+ ok t_cmp $read, $real, 'new($data, $offset, $len)/buffer';
+ ok t_cmp $rlen, length($read), 'new($data, $offse, $lent)/len';
+ }
+
+ # new: offset+ too big len
+ {
+ my $data = "foobartar";
+ my $offset = 3;
+ my $len = 10;
+ my $real = substr $data, $offset, $len;
+ my $b = eval { APR::Bucket->new($ba, $data, $offset, $len) };
+ ok t_cmp $@,
+ qr/the length argument can't be bigger than the total/,
+ 'new($data, $offset, $len_too_big)';
+ }
+
+ # modification of the source variable, affects the data
+ # inside the bucket
+ {
+ my $data = "A" x 10;
+ my $orig = $data;
+ my $b = APR::Bucket->new($ba, $data);
+ $data =~ s/^..../BBBB/;
+ $b->read(my $read);
+ ok t_cmp $read, $data,
+ "data inside the bucket should get affected by " .
+ "the changes to the Perl variable it's created from";
+ }
+
+
+ # APR::Bucket->new() with the argument PADTMP (which happens when
+ # some function is re-entered) and the same SV is passed to
+ # different buckets, which must be detected and copied away.
+ {
+ my @buckets = ();
+ my @data = qw(ABCD EF);
+ my @received = ();
+ for my $str (@data) {
+ my $b = func($ba, $str);
+ push @buckets, $b;
+ }
+
+ # the creating of buckets and reading from them is done
+ # separately on purpose
+ for my $b (@buckets) {
+ $b->read(my $out);
+ push @received, $out;
+ }
+
+ # here we used to get: two pv: "ef\0d"\0, "ef"\0, as you can see
+ # the first bucket had corrupted data.
+ my @expected = map { lc } @data;
+ ok t_cmp \@received, \@expected, "new(PADTMP SV)";
+
+ # this function will pass the same SV to new(), causing two
+ # buckets point to the same SV, and having the latest bucket's
+ # data override the previous one
+ sub func {
+ my $ba = shift;
+ my $data = shift;
+ return APR::Bucket->new($ba, lc $data);
+ }
+
+ }
+
+ # read data is tainted
+ {
+ my $data = "xxx";
+ my $b = APR::Bucket->new($ba, $data);
+ $b->read(my $read);
+ ok t_cmp $read, $data, 'new($data)';
+ ok TestCommon::Utils::is_tainted($read);
+ }
+
+ # remove/destroy
+ {
+ my $b = APR::Bucket->new($ba, "aaa");
+ # remove $b when it's not attached to anything (not sure if
+ # that should be an error)
+ $b->remove;
+ ok 1;
+
+ # a dangling bucket needs to be destroyed
+ $b->destroy;
+ ok 1;
+
+ # real remove from bb is tested in many other filter tests
+ }
+
+ # setaside
+ {
+ my $data = "A" x 10;
+ my $expected = $data;
+ my $b = APR::Bucket->new($ba, $data);
+ my $status = $b->setaside($pool);
+ ok t_cmp $status, APR::Const::SUCCESS, "setaside status";
+ $data =~ s/^..../BBBB/;
+ $b->read(my $read);
+ ok t_cmp $read, $expected,
+ "data inside the setaside bucket is unaffected by " .
+ "changes to the Perl variable it's created from";
+ $b->destroy;
+ }
+
+ # alloc_create on out-of-scope pools
+ {
+ # later may move that into a dedicated bucket_alloc test
+ my $ba = APR::BucketAlloc->new(APR::Pool->new);
+ # here if the pool is gone of scope destroy() will segfault
+ $ba->destroy;
+ ok 1;
+ }
+
+ # setaside on out-of-scope pools
+ {
+ # note that at the moment APR internally handles the situation
+ # when the pool goes out of scope, so modperl doesn't need to do
+ # any special handling of the pool object passed to setaside()
+ # to insure that it survives as long as $b is alive
+ #
+ # to make sure that this doesn't change internally in APR, the
+ # sub-test remains here
+ my $data = "A" x 10;
+ my $orig = $data;
+ my $b = APR::Bucket->new($ba, $data);
+ my $status = $b->setaside(APR::Pool->new);
+ ok t_cmp $status, APR::Const::SUCCESS, "setaside status";
+
+ # try to overwrite the temp pool data
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+
+ # now test that we are still OK
+ $b->read(my $read);
+ ok t_cmp $read, $data,
+ "data inside the setaside bucket is not corrupted";
+ $b->destroy;
+ }
+
+ $ba->destroy;
+}
+
+1;
+
diff --git a/2_0_13/t/lib/TestAPRlib/date.pm b/2_0_13/t/lib/TestAPRlib/date.pm
new file mode 100644
index 0000000..2f3dd80
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/date.pm
@@ -0,0 +1,72 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::date;
+
+# testing APR::Date API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Date ();
+
+my @http_dates = (
+ 'Sun, 06 Nov 1994 08:49:37 GMT', # RFC 822, updated by RFC 1123
+ 'Sunday, 06-Nov-94 08:49:37 GMT', # RFC 850, obsoleted by RFC 1036
+ 'Sun Nov 6 08:49:37 1994', # ANSI C's asctime() format
+);
+
+my @rfc_dates = (
+ 'Sun, 06 Nov 1994 08:49:37 GMT' , # RFC 822, updated by RFC 1123
+ 'Sunday, 06-Nov-94 08:49:37 GMT', # RFC 850, obsoleted by RFC 1036
+ 'Sun Nov 6 08:49:37 1994', # ANSI C's asctime() format
+ 'Sun, 6 Nov 1994 08:49:37 GMT', # RFC 822, updated by RFC 1123
+ 'Sun, 06 Nov 94 08:49:37 GMT', # RFC 822
+ 'Sun, 6 Nov 94 08:49:37 GMT', # RFC 822
+ 'Sun, 06 Nov 94 8:49:37 GMT', # Unknown [Elm 70.85]
+ 'Sun, 6 Nov 94 8:49:37 GMT', # Unknown [Elm 70.85]
+ 'Sun, 6 Nov 1994 08:49:37 GMT', # Unknown [Postfix]
+);
+
+my @bogus_dates = (
+ 'Sun, 06 Nov 94 08:49 GMT', # Unknown [drtr@ast.cam.ac.uk]
+ 'Sun, 6 Nov 94 08:49 GMT', # Unknown [drtr@ast.cam.ac.uk]
+);
+
+my $date_msec = 784111777;
+my $bogus_date_msec = 784111740;
+
+sub num_of_tests {
+ return @http_dates + @rfc_dates + @bogus_dates;
+}
+
+sub test {
+
+ # parse_http
+ for my $date_str (@http_dates) {
+ ok t_cmp(APR::Date::parse_http($date_str),
+ $date_msec,
+ "parse_http: $date_str");
+ #t_debug "testing : parse_http: $date_str";
+ }
+
+ # parse_rfc
+ for my $date_str (@rfc_dates) {
+ ok t_cmp(APR::Date::parse_rfc($date_str),
+ $date_msec,
+ "parse_rfc: $date_str");
+ #t_debug "testing : parse_rfc: $date_str";
+ }
+
+ # parse_rfc (bogus formats)
+ for my $date_str (@bogus_dates) {
+ ok t_cmp(APR::Date::parse_rfc($date_str),
+ $bogus_date_msec,
+ "parse_rfc: $date_str");
+ #t_debug "testing : parse_rfc: $date_str";
+ }
+
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/error.pm b/2_0_13/t/lib/TestAPRlib/error.pm
new file mode 100644
index 0000000..233045c
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/error.pm
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::error;
+
+# testing APR::Error API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Error;
+
+sub num_of_tests {
+ return 1;
+}
+
+sub test {
+ ok 1;
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/finfo.pm b/2_0_13/t/lib/TestAPRlib/finfo.pm
new file mode 100644
index 0000000..1f36a92
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/finfo.pm
@@ -0,0 +1,172 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::finfo;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+use Apache::TestConfig;
+
+use File::Spec::Functions qw(catfile);
+use Fcntl qw(:mode);
+
+use APR::Finfo ();
+use APR::Pool ();
+
+use constant WIN32 => Apache::TestConfig::WIN32;
+use constant OSX => Apache::TestConfig::OSX;
+
+use constant APACHE_2_0_49_PLUS => have_min_apache_version('2.0.49');
+use constant APACHE_2_2_PLUS => have_min_apache_version('2.2.0');
+
+use APR::Const -compile => qw(SUCCESS FINFO_NORM FINFO_PROT FILETYPE_REG
+ FPROT_WREAD FPROT_WWRITE
+ FPROT_WEXECUTE);
+
+sub num_of_tests {
+ return 27;
+}
+
+sub test {
+
+ # for the file to be tested, use the httpd.conf generated
+ # by testing, so that it has a ctime that won't (usually)
+ # encounter a bug in Win32's stat() function for files that
+ # span across DST season boundaries.
+ my $file = catfile Apache::Test::vars->{t_dir}, 'conf', 'httpd.conf';
+
+ my $pool = APR::Pool->new();
+ # populate the finfo struct first
+ my $wanted = APR::Const::FINFO_NORM;
+ if (WIN32) {
+ $wanted &= ~APR::Const::FINFO_PROT;
+ }
+ my $finfo = APR::Finfo::stat($file, $wanted, $pool);
+
+ ok $finfo->isa('APR::Finfo');
+
+ # now, get information from perl's stat()
+ my %stat;
+
+ @stat{qw(device inode protection nlink user group size atime mtime
+ ctime)} = (stat $file)[0..5, 7..10];
+
+ compare_with_perl($finfo, \%stat);
+
+ # tests for stuff not in perl's stat
+ {
+ # BACK_COMPAT_MARKER - fixed as of 2.0.49.
+ if (WIN32 && !APACHE_2_0_49_PLUS) {
+ skip "finfo.fname requires Apache 2.0.49 or later", 0;
+ }
+ else {
+ ok t_cmp($finfo->fname,
+ $file,
+ '$finfo->fname()');
+ }
+
+ ok t_cmp($finfo->filetype,
+ APR::Const::FILETYPE_REG,
+ '$finfo->filetype()');
+ }
+
+ # stat() on out-of-scope pools
+ {
+ my $finfo = APR::Finfo::stat($file, $wanted, APR::Pool->new);
+
+ # try to overwrite the temp pool data
+ require APR::Table;
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+
+ # now test that we are still OK
+ compare_with_perl($finfo, \%stat);
+ }
+
+}
+
+
+sub compare_with_perl {
+ my ($finfo, $stat) = @_;
+ # skip certain tests on Win32 and others
+ my %skip = ();
+
+ if (WIN32) {
+ # atime is wrong on NTFS, but OK on FAT32
+ %skip = map {$_ => 1} qw(device inode user group atime);
+ }
+ elsif (OSX) {
+ # XXX both apr and perl report incorrect group values. sometimes.
+ # XXX skip until we can really figure out what is going on.
+ %skip = (group => 1);
+ }
+
+ # compare stat fields between perl and apr_stat
+ {
+ foreach my $method (qw(device inode nlink user group
+ size atime mtime ctime)) {
+ if ($skip{$method}) {
+ skip "different file semantics", 0;
+ }
+ else {
+ ok t_cmp($finfo->$method(),
+ $stat->{$method},
+ "\$finfo->$method()");
+ }
+ }
+ }
+
+ # stat tests (same as perl's stat)
+ {
+
+ # XXX: untested
+ # ->name
+
+ # XXX: are there any platforms csize is available at all?
+ # We don't want to see the skipped message all the time if
+ # it's not really used anywhere
+ # if (my $csize = $finfo->csize) {
+ # # The storage size is at least as big as the file size
+ # # perl's stat() doesn't have the equivalent of csize
+ # t_debug "csize=$csize, size=$stat{size}";
+ # ok $csize >= $stat{size};
+ # }
+ # else {
+ # skip "csize is not available on this platform", 0;
+ # }
+
+ # match world bits
+
+ # on Win32, there's a bug in the apr library supplied
+ # with Apache/2.2 that causes the following two tests
+ # to fail. This is slated to be fixed after apr-1.2.7.
+ if (WIN32 and APACHE_2_2_PLUS) {
+ skip "broken apr stat on Win32", 0;
+ }
+ else {
+ ok t_cmp($finfo->protection & APR::Const::FPROT_WREAD,
+ $stat->{protection} & S_IROTH,
+ '$finfo->protection() & APR::Const::FPROT_WREAD');
+ }
+ if (WIN32 and APACHE_2_2_PLUS) {
+ skip "broken apr stat on Win32", 0;
+ }
+ else {
+ ok t_cmp($finfo->protection & APR::Const::FPROT_WWRITE,
+ $stat->{protection} & S_IWOTH,
+ '$finfo->protection() & APR::Const::FPROT_WWRITE');
+ }
+ if (WIN32) {
+ skip "different file semantics", 0;
+ }
+ else {
+ ok t_cmp($finfo->protection & APR::Const::FPROT_WEXECUTE,
+ $stat->{protection} & S_IXOTH,
+ '$finfo->protection() & APR::Const::FPROT_WEXECUTE');
+ }
+ }
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/os.pm b/2_0_13/t/lib/TestAPRlib/os.pm
new file mode 100644
index 0000000..12344fb
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/os.pm
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::os;
+
+# testing APR::OS API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::OS ();
+
+sub num_of_tests {
+ return 1;
+}
+
+sub test {
+ ok 1;
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/pool.pm b/2_0_13/t/lib/TestAPRlib/pool.pm
new file mode 100644
index 0000000..519cba7
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/pool.pm
@@ -0,0 +1,502 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::pool;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use APR::Pool ();
+use APR::Table ();
+
+sub num_of_tests {
+ return 77;
+}
+
+sub test {
+
+ my $pool = APR::Pool->new();
+ my $table = APR::Table::make($pool, 2);
+
+ ### custom pools ###
+
+ # test: explicit pool object destroy destroys the custom pool
+ {
+ my $p = APR::Pool->new;
+
+ $p->cleanup_register(\&set_cleanup, [$table, 'new destroy']);
+
+ ok t_cmp(ancestry_count($p), 1,
+ "a new pool has one ancestor: the global pool");
+
+ # explicity destroy the object
+ $p->destroy;
+
+ my @notes = $table->get('cleanup');
+
+ ok t_cmp(scalar(@notes), 1, "should be 1 note");
+
+ ok t_cmp($notes[0], 'new destroy');
+
+ $table->clear;
+ }
+
+
+ # test: lexical scoping DESTROYs the custom pool
+ {
+ {
+ my $p = APR::Pool->new;
+
+ ok t_cmp(ancestry_count($p), 1,
+ "a new pool has one ancestor: the global pool");
+
+ $p->cleanup_register(\&set_cleanup, [$table, 'new scoped']);
+ }
+
+ my @notes = $table->get('cleanup');
+
+ ok t_cmp(scalar(@notes), 1, "should be 1 note");
+
+ ok t_cmp($notes[0], 'new scoped');
+
+ $table->clear;
+ }
+
+
+
+ ### custom pools + sub-pools ###
+
+ # test: basic pool and sub-pool tests + implicit destroy of pool objects
+ {
+ {
+ my ($pp, $sp) = both_pools_create_ok($table);
+ }
+
+ both_pools_destroy_ok($table);
+
+ $table->clear;
+ }
+
+
+ # test: explicitly destroying a parent pool should destroy its
+ # sub-pool
+ {
+ my ($pp, $sp) = both_pools_create_ok($table);
+
+ # destroying $pp should destroy the subpool $sp too
+ $pp->destroy;
+
+ both_pools_destroy_ok($table);
+
+ $table->clear;
+ }
+
+
+
+ # test: destroying a sub-pool before the parent pool
+ {
+ my ($pp, $sp) = both_pools_create_ok($table);
+
+ $sp->destroy;
+ $pp->destroy;
+
+ both_pools_destroy_ok($table);
+
+ $table->clear;
+ }
+
+
+ # test: destroying a sub-pool explicitly after the parent pool destroy
+
+ # the parent pool should have already destroyed the child pool, so
+ # the object is invalid
+ {
+ my ($pp, $sp) = both_pools_create_ok($table);
+
+ $pp->destroy;
+ $sp->destroy;
+
+ both_pools_destroy_ok($table);
+
+ $table->clear;
+ }
+
+
+ # test: destroying a sub-pool before the parent pool and trying to
+ # call APR::Pool methods on the a subpool object which points to a
+ # destroyed pool
+ {
+ my ($pp, $sp) = both_pools_create_ok($table);
+
+ # parent pool destroys child pool
+ $pp->destroy;
+
+ # this should "gracefully" fail, since $sp's guts were
+ # destroyed when the parent pool was destroyed
+ eval { $pp = $sp->parent_get };
+ ok t_cmp($@,
+ qr/invalid pool object/,
+ "parent pool destroys child pool");
+
+ # since pool $sp now contains 0 pointer, if we try to make a
+ # new pool out of it, it's the same as APR->new (i.e. it'll
+ # use the global top level pool for it), so the resulting pool
+ # should have an ancestry length of exactly 1
+ my $ssp = $sp->new;
+ ok t_cmp(ancestry_count($ssp), 1,
+ "a new pool has one ancestor: the global pool");
+
+
+ both_pools_destroy_ok($table);
+
+ $table->clear;
+ }
+
+ # test: make sure that one pool won't destroy/affect another pool,
+ # which happened to be allocated at the same memory address after
+ # the pointer to the first pool was destroyed
+ {
+ my $pp2;
+ {
+ my $pp = APR::Pool->new;
+ $pp->destroy;
+ # $pp2 ideally should take the exact place of apr_pool
+ # previously pointed to by $pp
+ $pp2 = APR::Pool->new;
+ # $pp object didn't go away yet (it'll when exiting this
+ # scope). in the previous implementation, $pp will be
+ # destroyed second time on the exit of the scope and it
+ # could happen to work, because $pp2 pointer has allocated
+ # exactly the same address. and if so it would have killed
+ # the pool that $pp2 points to
+
+ # this should "gracefully" fail, since $pp's guts were
+ # destroyed when the parent pool was destroyed
+ # must make sure that it won't try to hijack the new pool
+ # $pp2 that (hopefully) took over $pp's place
+ eval { $pp->parent_get };
+ ok t_cmp($@,
+ qr/invalid pool object/,
+ "a dead pool is a dead pool");
+ }
+
+ # next make sure that $pp2's pool is still alive
+ $pp2->cleanup_register(\&set_cleanup, [$table, 'overtake']);
+ $pp2->destroy;
+
+ my @notes = $table->get('cleanup');
+
+ ok t_cmp(scalar(@notes), 1, "should be 1 note");
+ ok t_cmp($notes[0], 'overtake');
+
+ $table->clear;
+
+ }
+
+ # test: similar to the previous test, but this time, the parent
+ # pool destroys the child pool. a second allocation of a new pair
+ # of the parent and child pools take over exactly the same
+ # allocations. so if there are any ghost objects, they must not
+ # find the other pools and use them as they own. for example they
+ # could destroy the pools, and the perl objects of the pair would
+ # have no idea that someone has destroyed the pools without their
+ # knowledge. the previous implementation suffered from this
+ # problem. the new implementation uses an SV which is stored in
+ # the object and in the pool. when the pool is destroyed the SV
+ # gets its IVX pointer set to 0, which affects any perl object
+ # that is a ref to that SV. so once an apr pool is destroyed all
+ # perl objects pointing to it get automatically invalidated and
+ # there is no risk of hijacking newly created pools that happen to
+ # be at the same memory address.
+
+ {
+ my ($pp2, $sp2);
+ {
+ my $pp = APR::Pool->new;
+ my $sp = $pp->new;
+ # parent destroys $sp
+ $pp->destroy;
+
+ # hopefully these pool will take over the $pp and $sp
+ # allocations
+ ($pp2, $sp2) = both_pools_create_ok($table);
+ }
+
+ # $pp and $sp shouldn't have triggered any cleanups
+ my @notes = $table->get('cleanup');
+ ok t_cmp(scalar(@notes), 0, "should be 0 notes");
+ $table->clear;
+
+ # parent pool destroys child pool
+ $pp2->destroy;
+
+ both_pools_destroy_ok($table);
+
+ $table->clear;
+ }
+
+ # test: only when the last references to the pool object is gone
+ # it should get destroyed
+ {
+
+ my $cp;
+
+ {
+ my $sp = APR::Pool->new();
+
+ $sp->cleanup_register(\&set_cleanup, [$table, 'several references']);
+
+ $cp = $sp;
+ # destroy of $sp shouldn't call apr_pool_destroy, because
+ # $cp still references to it
+ }
+
+ my @notes = $table->get('cleanup');
+ ok t_cmp(scalar(@notes), 0, "should be 0 notes");
+ $table->clear;
+
+ # now the last copy is gone and the cleanup hooks will be called
+ $cp->destroy;
+
+ @notes = $table->get('cleanup');
+ ok t_cmp(scalar(@notes), 1, "should be 1 note");
+ ok t_cmp($notes[0], 'several references');
+
+ $table->clear;
+ }
+ {
+ # and another variation
+ my $pp = APR::Pool->new();
+ my $sp = $pp->new;
+
+ my $gp = $pp->parent_get;
+ my $pp2 = $sp->parent_get;
+
+ # parent destroys children
+ $pp->destroy;
+
+ # grand parent ($pool) is undestroyable (core pool)
+ $gp->destroy;
+
+ # now all custom pools are destroyed - $sp and $pp2 point nowhere
+ $pp2->destroy;
+ $sp->destroy;
+
+ ok 1;
+ }
+
+ # cleanup_register using a function name as a callback
+ {
+ {
+ my $p = APR::Pool->new;
+ $p->cleanup_register('set_cleanup', [$table, 'function name']);
+ }
+
+ my @notes = $table->get('cleanup');
+ ok t_cmp($notes[0], 'function name', "function name callback");
+
+ $table->clear;
+ }
+
+ # cleanup_register using an anon sub callback
+ {
+ {
+ my $p = APR::Pool->new;
+
+ $p->cleanup_register(sub { &set_cleanup }, [$table, 'anon sub']);
+ }
+
+ my @notes = $table->get('cleanup');
+ ok t_cmp($notes[0], 'anon sub', "anon callback");
+
+ $table->clear;
+ }
+
+ # registered callbacks are run in reversed order LIFO
+ {
+ {
+ my $p = APR::Pool->new;
+
+ $p->cleanup_register(\&add_cleanup, [$table, 'first']);
+ $p->cleanup_register(\&add_cleanup, [$table, 'second']);
+ }
+
+ my @notes = $table->get('cleanup');
+ ok t_cmp($notes[0], 'second', "two cleanup functions");
+ ok t_cmp($notes[1], 'first', "two cleanup functions");
+
+ $table->clear;
+ }
+
+ # undefined cleanup subs
+ {
+ my $p = APR::Pool->new;
+ $p->cleanup_register('TestAPR::pool::some_non_existing_sub', 1);
+
+ my @warnings;
+ local $SIG{__WARN__} = sub {push @warnings, @_};
+ $p->destroy;
+
+ ok t_cmp($warnings[0],
+ qr/Undefined subroutine/,
+ "non existing function");
+ }
+ {
+ my $p = APR::Pool->new;
+ $p->cleanup_register(\&non_existing1, 1);
+
+ my @warnings;
+ local $SIG{__WARN__} = sub {push @warnings, @_};
+ $p->destroy;
+
+ ok t_cmp($warnings[0],
+ qr/Undefined subroutine/,
+ "non existing function");
+ }
+
+ # cleanups throwing exceptions
+ {
+ my $p = APR::Pool->new;
+ $p->cleanup_register(sub {die "1\n"}, 1);
+ $p->cleanup_register(sub {die "2\n"}, 1);
+
+ my @warnings;
+ local $SIG{__WARN__} = sub {push @warnings, @_};
+ local $@="to be preserved";
+ undef $p;
+
+ ok t_cmp(\@warnings,
+ [map "APR::Pool: cleanup died: $_\n", 2, 1],
+ "exceptions thrown by cleanups");
+ ok t_cmp($@, "to be preserved", '$@ is preserved');
+ }
+
+ ### $p->clear ###
+ {
+ my ($pp, $sp) = both_pools_create_ok($table);
+ $pp->clear;
+ # both pools should have run their cleanups
+ both_pools_destroy_ok($table);
+
+ # sub-pool $sp should be now bogus, as clear() destroys
+ # subpools
+ eval { $sp->parent_get };
+ ok t_cmp($@,
+ qr/invalid pool object/,
+ "clear destroys sub pools");
+
+ # now we should be able to use the parent pool without
+ # allocating it
+ $pp->cleanup_register(\&set_cleanup, [$table, 're-using pool']);
+ $pp->destroy;
+
+ my @notes = $table->get('cleanup');
+ ok t_cmp('re-using pool', $notes[0]);
+
+ $table->clear;
+ }
+
+
+ # a pool can be tagged, so when doing low level apr_pool tracing
+ # (when apr is compiled with -DAPR_POOL_DEBUG) it's possible to
+ # grep(1) for a certain tag, so it's a useful method
+ {
+ my $p = APR::Pool->new;
+ $p->tag("my pool");
+
+ # though there is no way we can get back the value to test,
+ # since there is no apr_pool_tag read accessor
+ ok 1;
+ }
+
+ # out-of-scope pools
+ {
+ my $sp = APR::Pool->new->new;
+ # the parent temp pool must stick around
+ ok t_cmp(2, ancestry_count($sp),
+ "parent pool is still alive + global pool");
+ }
+
+ # other stuff
+ {
+ my $p = APR::Pool->new;
+
+ # find some method that wants a pool object and try to pass it
+ # an object that was already destroyed e.g. APR::Table::make($p, 2);
+
+ # only available with -DAPR_POOL_DEBUG
+ #my $num_bytes = $p->num_bytes;
+ #ok $num_bytes;
+
+ }
+}
+
+# returns how many ancestor generations the pool has (parent,
+# grandparent, etc.)
+sub ancestry_count {
+ my $child = shift;
+ my $gen = 0;
+ while (my $parent = $child->parent_get) {
+ # prevent possible endless loops
+ die "child pool reports to be its own parent, corruption!"
+ if $parent == $child;
+ $gen++;
+ die "child knows its parent, but the parent denies having that child"
+ unless $parent->is_ancestor($child);
+ $child = $parent;
+ }
+ return $gen;
+}
+
+sub add_cleanup {
+ my $arg = shift;
+ debug "adding cleanup note: $arg->[1]";
+ $arg->[0]->add(cleanup => $arg->[1]);
+ 1;
+}
+
+sub set_cleanup {
+ my $arg = shift;
+ debug "setting cleanup note: $arg->[1]";
+ $arg->[0]->set(cleanup => $arg->[1]);
+ 1;
+}
+
+# +4 tests
+sub both_pools_create_ok {
+ my $table = shift;
+
+ my $pp = APR::Pool->new;
+
+ ok t_cmp(1, $pp->isa('APR::Pool'), "isa('APR::Pool')");
+
+ ok t_cmp(1, ancestry_count($pp),
+ "a new pool has one ancestor: the global pool");
+
+ my $sp = $pp->new;
+
+ ok t_cmp($sp->isa('APR::Pool'), 1, "isa('APR::Pool')");
+
+ ok t_cmp(ancestry_count($sp), 2,
+ "a subpool has 2 ancestors: the parent and global pools");
+
+ $pp->cleanup_register(\&add_cleanup, [$table, 'parent']);
+ $sp->cleanup_register(\&set_cleanup, [$table, 'child']);
+
+ return ($pp, $sp);
+
+}
+
+# +3 tests
+sub both_pools_destroy_ok {
+ my $table = shift;
+ my @notes = $table->get('cleanup');
+
+ ok t_cmp(scalar(@notes), 2, "should be 2 notes");
+ ok t_cmp($notes[0], 'child');
+ ok t_cmp($notes[1], 'parent');
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/status.pm b/2_0_13/t/lib/TestAPRlib/status.pm
new file mode 100644
index 0000000..6bf7f50
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/status.pm
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::status;
+
+# Testing APR::Status
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Const -compile => qw(EAGAIN ENOPOLL);
+use APR::Status ();
+
+sub num_of_tests {
+ return 2;
+}
+
+sub test {
+ ok APR::Status::is_EAGAIN(APR::Const::EAGAIN);
+ ok ! APR::Status::is_EAGAIN(APR::Const::ENOPOLL);
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/string.pm b/2_0_13/t/lib/TestAPRlib/string.pm
new file mode 100644
index 0000000..9185e3b
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/string.pm
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::string;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::String ();
+
+my %size_string = (
+ '-1' => " - ",
+ 0 => " 0 ",
+ 42 => " 42 ",
+ 42_000 => " 41K",
+ 42_000_000 => " 40M",
+# 42_000_000_000 => "40G",
+);
+
+sub num_of_tests {
+ return scalar keys %size_string;
+}
+
+sub test {
+
+ t_debug("size_string");
+ while (my ($k, $v) = each %size_string) {
+ ok t_cmp($v, APR::String::format_size($k));
+ }
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/table.pm b/2_0_13/t/lib/TestAPRlib/table.pm
new file mode 100644
index 0000000..3310674
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/table.pm
@@ -0,0 +1,380 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::table;
+
+# testing APR::Table API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Table ();
+use APR::Pool ();
+
+use APR::Const -compile => ':table';
+
+use constant TABLE_SIZE => 20;
+our $filter_count;
+
+sub num_of_tests {
+ my $tests = 56;
+
+ # tied hash values() for a table w/ multiple values for the same
+ # key
+ $tests += 2 if $] >= 5.008;
+
+ return $tests;
+}
+
+sub test {
+
+ $filter_count = 0;
+ my $pool = APR::Pool->new();
+ my $table = APR::Table::make($pool, TABLE_SIZE);
+
+ ok UNIVERSAL::isa($table, 'APR::Table');
+
+ # get on non-existing key
+ {
+ # in scalar context
+ my $val = $table->get('foo');
+ ok t_cmp($val, undef, '$val = $table->get("no_such_key")');
+
+ # in list context
+ my @val = $table->get('foo');
+ ok t_cmp(+@val, 0, '@val = $table->get("no_such_key")');
+ }
+
+ # set/add/get/copy normal values
+ {
+ $table->set(foo => 'bar');
+
+ # get scalar context
+ my $val = $table->get('foo');
+ ok t_cmp($val, 'bar', '$val = $table->get("foo")');
+
+ # add + get list context
+ $table->add(foo => 'tar');
+ $table->add(foo => 'kar');
+ my @val = $table->get('foo');
+ ok @val == 3 &&
+ $val[0] eq 'bar' &&
+ $val[1] eq 'tar' &&
+ $val[2] eq 'kar';
+
+ # copy
+ $table->set(too => 'boo');
+ my $table_copy = $table->copy($pool);
+ my $val_copy = $table->get('too');
+ ok t_cmp($val_copy, 'boo', '$val = $table->get("too")');
+ my @val_copy = $table_copy->get('foo');
+ ok @val_copy == 3 &&
+ $val_copy[0] eq 'bar' &&
+ $val_copy[1] eq 'tar' &&
+ $val_copy[2] eq 'kar';
+ }
+
+ # make sure 0 comes through as 0 and not undef
+ {
+ $table->set(foo => 0);
+ my $zero = $table->get('foo');
+ ok t_cmp($zero, 0, 'table value 0 is not undef');
+ }
+
+ # unset
+ {
+ $table->set(foo => "bar");
+ $table->unset('foo');
+ ok t_cmp(+$table->get('foo'), undef, '$table->unset("foo")');
+ }
+
+ # merge
+ {
+ $table->set( merge => '1');
+ $table->merge(merge => 'a');
+ my $val = $table->get('merge');
+ ok t_cmp($val, "1, a", 'one val $table->merge(...)');
+
+ # if there is more than one value for the same key, merge does
+ # the job only for the first value
+ $table->add( merge => '2');
+ $table->merge(merge => 'b');
+ my @val = $table->get('merge');
+ ok t_cmp($val[0], "1, a, b", '$table->merge(...)');
+ ok t_cmp($val[1], "2", 'two values $table->merge(...)');
+
+ # if the key is not found, works like set/add
+ $table->merge(miss => 'a');
+ my $val_miss = $table->get('miss');
+ ok t_cmp($val_miss, "a", 'no value $table->merge(...)');
+ }
+
+ # clear
+ {
+ $table->set(foo => 0);
+ $table->set(bar => 1);
+ $table->clear();
+ # t_cmp forces scalar context on get
+ ok t_cmp($table->get('foo'), undef, '$table->clear');
+ ok t_cmp($table->get('bar'), undef, '$table->clear');
+ }
+
+ # filtering
+ {
+ for (1..TABLE_SIZE) {
+ $table->set(chr($_+97), $_);
+ }
+
+ # Simple filtering
+ $filter_count = 0;
+ $table->do("my_filter");
+ ok t_cmp($filter_count, TABLE_SIZE);
+
+ # Filtering aborting in the middle
+ $filter_count = 0;
+ $table->do("my_filter_stop");
+ ok t_cmp($filter_count, int(TABLE_SIZE)/2) ;
+
+ # Filtering with anon sub
+ $filter_count=0;
+ $table->do(sub {
+ my ($key,$value) = @_;
+ $filter_count++;
+ unless ($key eq chr($value+97)) {
+ die "arguments I recieved are bogus($key,$value)";
+ }
+ return 1;
+ });
+
+ ok t_cmp($filter_count, TABLE_SIZE, "table size");
+
+ $filter_count = 0;
+ $table->do("my_filter", "c", "b", "e");
+ ok t_cmp($filter_count, 3, "table size");
+ }
+
+ #Tied interface
+ {
+ my $table = APR::Table::make($pool, TABLE_SIZE);
+
+ ok UNIVERSAL::isa($table, 'HASH');
+
+ ok UNIVERSAL::isa($table, 'HASH') && tied(%$table);
+
+ ok $table->{'foo'} = 'bar';
+
+ # scalar context
+ ok $table->{'foo'} eq 'bar';
+
+ ok delete $table->{'foo'} || 1;
+
+ ok not exists $table->{'foo'};
+
+ for (1..TABLE_SIZE) {
+ $table->{chr($_+97)} = $_;
+ }
+
+ $filter_count = 0;
+ foreach my $key (sort keys %$table) {
+ my_filter($key, $table->{$key});
+ }
+ ok $filter_count == TABLE_SIZE;
+ }
+
+
+ # each, values
+ {
+ my $table = APR::Table::make($pool, 2);
+
+ $table->add("first" => 1);
+ $table->add("second" => 2);
+ $table->add("first" => 3);
+
+ my $i = 0;
+ while (my ($a,$b) = each %$table) {
+ my $key = ("first", "second")[$i % 2];
+ my $val = ++$i;
+
+ ok t_cmp $a, $key, "table each: key test";
+ ok t_cmp $b, $val, "table each: value test";
+ ok t_cmp $table->{$a}, $val, "table each: get test";
+
+ ok t_cmp tied(%$table)->FETCH($a), $val,
+ "table each: tied get test";
+ }
+
+ # this doesn't work with Perl < 5.8
+ if ($] >= 5.008) {
+ ok t_cmp "1,2,3", join(",", values %$table),
+ "table values";
+ ok t_cmp "first,1,second,2,first,3", join(",", %$table),
+ "table entries";
+ }
+ }
+
+ # overlap and compress routines
+ {
+ my $base = APR::Table::make($pool, TABLE_SIZE);
+ my $add = APR::Table::make($pool, TABLE_SIZE);
+
+ $base->set(foo => 'one');
+ $base->add(foo => 'two');
+
+ $add->set(foo => 'three');
+ $add->set(bar => 'beer');
+
+ my $overlay = $base->overlay($add, $pool);
+
+ my @foo = $overlay->get('foo');
+ my @bar = $overlay->get('bar');
+
+ ok t_cmp(+@foo, 3);
+ ok t_cmp($bar[0], 'beer');
+
+ my $overlay2 = $overlay->copy($pool);
+
+ # compress/merge
+ $overlay->compress(APR::Const::OVERLAP_TABLES_MERGE);
+ # $add first, then $base
+ ok t_cmp($overlay->get('foo'),
+ 'three, one, two',
+ "\$overlay->compress/merge");
+ ok t_cmp($overlay->get('bar'),
+ 'beer',
+ "\$overlay->compress/merge");
+
+ # compress/set
+ $overlay->compress(APR::Const::OVERLAP_TABLES_SET);
+ # $add first, then $base
+ ok t_cmp($overlay2->get('foo'),
+ 'three',
+ "\$overlay->compress/set");
+ ok t_cmp($overlay2->get('bar'),
+ 'beer',
+ "\$overlay->compress/set");
+ }
+
+ # overlap set
+ {
+ my $base = APR::Table::make($pool, TABLE_SIZE);
+ my $add = APR::Table::make($pool, TABLE_SIZE);
+
+ $base->set(bar => 'beer');
+ $base->set(foo => 'one');
+ $base->add(foo => 'two');
+
+ $add->set(foo => 'three');
+
+ $base->overlap($add, APR::Const::OVERLAP_TABLES_SET);
+
+ my @foo = $base->get('foo');
+ my @bar = $base->get('bar');
+
+ ok t_cmp(+@foo, 1, 'overlap/set');
+ ok t_cmp($foo[0], 'three');
+ ok t_cmp($bar[0], 'beer');
+ }
+
+ # overlap merge
+ {
+ my $base = APR::Table::make($pool, TABLE_SIZE);
+ my $add = APR::Table::make($pool, TABLE_SIZE);
+
+ $base->set(foo => 'one');
+ $base->add(foo => 'two');
+
+ $add->set(foo => 'three');
+ $add->set(bar => 'beer');
+
+ $base->overlap($add, APR::Const::OVERLAP_TABLES_MERGE);
+
+ my @foo = $base->get('foo');
+ my @bar = $base->get('bar');
+
+ ok t_cmp(+@foo, 1, 'overlap/set');
+ ok t_cmp($foo[0], 'one, two, three');
+ ok t_cmp($bar[0], 'beer');
+ }
+
+
+ # temp pool objects.
+ # testing here that the temp pool object doesn't go out of scope
+ # before the object based on it was freed. the following tests
+ # were previously segfaulting when using apr1/httpd2.1 built w/
+ # --enable-pool-debug CPPFLAGS="-DAPR_BUCKET_DEBUG",
+ # the affected methods are:
+ # - make
+ # - copy
+ # - overlay
+ {
+ {
+ my $table = APR::Table::make(APR::Pool->new, 10);
+ $table->set($_ => $_) for 1..20;
+ ok t_cmp $table->get(20), 20, "no segfault";
+ }
+
+ my $pool = APR::Pool->new;
+ my $table = APR::Table::make($pool, 10);
+ $table->set($_ => $_) for 1..20;
+ my $table_copy = $table->copy($pool->new);
+ {
+ # verify that the temp pool used to create $table_copy was
+ # not freed, by allocating a new table to fill with a
+ # different data. if that former pool was freed
+ # $table_copy will now contain bogus data (and may
+ # segfault)
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'a'..'z';
+ ok t_cmp $table->get('z'), 'z', "helper test";
+
+ }
+ ok t_cmp $table_copy->get(20), 20, "no segfault/valid data";
+
+ my $table2 = APR::Table::make($pool, 1);
+ $table2->set($_**2 => $_**2) for 1..20;
+ my $table2_copy = APR::Table::make($pool, 1);
+ $table2_copy->set($_ => $_) for 1..20;
+
+ my $overlay = $table2_copy->overlay($table2, $pool->new);
+ {
+ # see the comment for above's:
+ # $table_copy = $table->copy(APR::Pool->new);
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+ ok t_cmp $table->get('za'), 'za', "helper test";
+
+ }
+ ok t_cmp $overlay->get(20), 20, "no segfault/valid data";
+ }
+ {
+ {
+ my $p = APR::Pool->new;
+ $p->cleanup_register(sub { "whatever" });
+ $table = APR::Table::make($p, 10)
+ };
+ $table->set(a => 5);
+ ok t_cmp $table->get("a"), 5, "no segfault";
+ }
+
+}
+
+sub my_filter {
+ my ($key, $value) = @_;
+ $filter_count++;
+ unless ($key eq chr($value+97)) {
+ die "arguments I received are bogus($key,$value)";
+ }
+ return 1;
+}
+
+sub my_filter_stop {
+ my ($key, $value) = @_;
+ $filter_count++;
+ unless ($key eq chr($value+97)) {
+ die "arguments I received are bogus($key,$value)";
+ }
+ return $filter_count == int(TABLE_SIZE)/2 ? 0 : 1;
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/threadmutex.pm b/2_0_13/t/lib/TestAPRlib/threadmutex.pm
new file mode 100644
index 0000000..c632a21
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/threadmutex.pm
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::threadmutex;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Const -compile => qw(EBUSY SUCCESS);
+use APR::Pool();
+
+sub num_of_tests {
+ return 5;
+}
+
+sub test {
+
+ require APR::ThreadMutex;
+
+ my $pool = APR::Pool->new();
+ my $mutex = APR::ThreadMutex->new($pool);
+
+ ok $mutex;
+
+ ok t_cmp($mutex->lock, APR::Const::SUCCESS,
+ 'lock == APR::Const::SUCCESS');
+
+#XXX: don't get what we expect on win23
+#need to use APR_STATUS_IS_EBUSY ?
+# ok t_cmp($mutex->trylock, APR::Const::EBUSY,
+# 'trylock == APR::Const::EBUSY');
+
+ ok t_cmp($mutex->unlock, APR::Const::SUCCESS,
+ 'unlock == APR::Const::SUCCESS');
+
+ # out-of-scope pool
+ {
+ my $mutex = APR::ThreadMutex->new(APR::Pool->new);
+ # try to overwrite the temp pool data
+ require APR::Table;
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+ # now test that we are still OK
+ ok t_cmp($mutex->lock, APR::Const::SUCCESS,
+ 'lock == APR::Const::SUCCESS');
+ ok t_cmp($mutex->unlock, APR::Const::SUCCESS,
+ 'unlock == APR::Const::SUCCESS');
+ }
+
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/threadrwlock.pm b/2_0_13/t/lib/TestAPRlib/threadrwlock.pm
new file mode 100644
index 0000000..df07afb
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/threadrwlock.pm
@@ -0,0 +1,40 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::threadrwlock;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Const -compile => qw(EBUSY SUCCESS);
+use APR::Pool();
+
+sub num_of_tests {
+ return 5;
+}
+
+sub test {
+
+ require APR::ThreadRWLock;
+
+ my $pool = APR::Pool->new();
+ my $mutex = APR::ThreadRWLock->new($pool);
+
+ ok $mutex;
+
+ ok t_cmp($mutex->rdlock, APR::Const::SUCCESS,
+ 'rdlock == APR::Const::SUCCESS');
+
+ ok t_cmp($mutex->unlock, APR::Const::SUCCESS,
+ 'unlock == APR::Const::SUCCESS');
+
+ ok t_cmp($mutex->wrlock, APR::Const::SUCCESS,
+ 'wrlock == APR::Const::SUCCESS');
+
+ ok t_cmp($mutex->unlock, APR::Const::SUCCESS,
+ 'unlock == APR::Const::SUCCESS');
+
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/uri.pm b/2_0_13/t/lib/TestAPRlib/uri.pm
new file mode 100644
index 0000000..8c01282
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/uri.pm
@@ -0,0 +1,189 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::uri;
+
+# Testing APR::URI (more tests in TestAPI::uri)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::URI ();
+use APR::Pool ();
+use APR::Const -compile => qw(URI_UNP_OMITSITEPART URI_UNP_OMITUSER
+ URI_UNP_REVEALPASSWORD URI_UNP_OMITQUERY
+ URI_UNP_OMITPASSWORD URI_UNP_OMITPATHINFO
+ );
+
+my %default_ports = (
+ ftp => 21,
+ gopher => 70,
+ http => 80,
+ https => 443,
+ nntp => 119,
+ prospero => 191,
+ snews => 563,
+ wais => 210,
+);
+
+my %url = (
+ scheme => ["http", "ftp" ],
+ user => ["user", "log" ],
+ password => ["password", "pass" ],
+ hostname => ["www.example.com", "ftp.example.com"],
+ port => [8000, 21 ],
+ path => ["/path/file.pl", "/pub" ],
+ query => ["query", undef ],
+ fragment => ["fragment", undef ],
+);
+
+my @keys_urls = qw(scheme user password hostname port path query
+ fragment);
+my @keys_hostinfo = qw(user password hostname port);
+
+sub num_of_tests {
+ return 36;
+}
+
+sub test {
+
+ my $pool = APR::Pool->new();
+
+ ### parse ###
+ my $url0 = sprintf "%s://%s:%s\@%s:%d%s?%s#%s",
+ map { $url{$_}[0] } @keys_urls;
+ # warn "URL: $url\n";
+ my $hostinfo0 = sprintf "%s:%s\@%s:%d",
+ map { $url{$_}[0] } @keys_hostinfo;
+
+ my $parsed = APR::URI->parse($pool, $url0);
+ ok $parsed;
+ ok $parsed->isa('APR::URI');
+
+ for my $method (keys %url) {
+ no strict 'refs';
+ ok t_cmp($parsed->$method, $url{$method}[0], $method);
+ }
+
+ ok t_cmp($parsed->hostinfo, $hostinfo0, "hostinfo");
+
+ for my $method (keys %url) {
+ no strict 'refs';
+ $parsed->$method($url{$method}[1]);
+ t_debug("$method: " . ($url{$method}[1]||'undef') .
+ " => " . ($parsed->$method||'undef'));
+ }
+
+ ### unparse ###
+ my $url_unparsed = $parsed->unparse;
+
+ # hostinfo is unaffected, since it's simply a field in the parsed
+ # record, and it's populated when parse is called, but when
+ # individual fields used to compose it are updated, it doesn't get
+ # updated: so we see the old value here
+ ok t_cmp($parsed->hostinfo, $hostinfo0, "hostinfo");
+
+ # - since 21 is the default port for ftp, unparse omits it
+ # - if no flags are passed to unparse, APR::Const::URI_UNP_OMITPASSWORD
+ # is passed by default -- it hides the password
+ my $url1 = sprintf "%s://%s\@%s%s",
+ map { $url{$_}[1] } qw(scheme user hostname path);
+ ok t_cmp($url_unparsed, $url1, "unparsed url");
+
+ # various unparse flags #
+ {
+ # restore the query/fragment fields first
+ my $query_new = "my_query";
+ my $fragment_new = "my_fragment";
+ $parsed->query($query_new);
+ $parsed->fragment($fragment_new);
+ local $url{query}[1] = $query_new;
+ local $url{fragment}[1] = $fragment_new;
+
+ # omit the site part
+ {
+ my $url_unparsed = $parsed->unparse(APR::Const::URI_UNP_OMITSITEPART);
+ my $url2 = sprintf "%s?%s#%s",
+ map { $url{$_}[1] } qw(path query fragment);
+ ok t_cmp($url_unparsed, $url2, "unparsed url: omit site");
+ }
+
+ # this time the password should appear as XXXXXXXX
+ {
+ local $url{password}[1] = "XXXXXXXX";
+ my $url_unparsed = $parsed->unparse(0);
+ my $url2 = sprintf "%s://%s:%s\@%s%s?%s#%s",
+ map { $url{$_}[1] } grep !/^port$/, @keys_urls;
+ ok t_cmp($url_unparsed, $url2, "unparsed url:reveal passwd");
+ }
+
+ # this time the user and the password should appear
+ {
+ my $url_unparsed = $parsed->unparse(APR::Const::URI_UNP_REVEALPASSWORD);
+ my $url2 = sprintf "%s://%s:%s\@%s%s?%s#%s",
+ map { $url{$_}[1] } grep !/^port$/, @keys_urls;
+ ok t_cmp($url_unparsed, $url2, "unparsed url:reveal passwd");
+ }
+
+ # omit the user part / show password
+ {
+ my $url_unparsed = $parsed->unparse(
+ APR::Const::URI_UNP_OMITUSER|APR::Const::URI_UNP_REVEALPASSWORD);
+ my $url2 = sprintf "%s://:%s\@%s%s?%s#%s",
+ map { $url{$_}[1] } grep !/^(port|user)$/, @keys_urls;
+ ok t_cmp($url_unparsed, $url2, "unparsed url: omit user");
+ }
+
+ # omit the path, query and fragment strings
+ {
+ my $url_unparsed = $parsed->unparse(
+ APR::Const::URI_UNP_OMITPATHINFO|APR::Const::URI_UNP_REVEALPASSWORD);
+ my $url2 = sprintf "%s://%s:%s\@%s", map { $url{$_}[1] }
+ grep !/^(port|path|query|fragment)$/, @keys_urls;
+ ok t_cmp($url_unparsed, $url2, "unparsed url: omit path");
+ }
+
+ # omit the query and fragment strings
+ {
+ my $url_unparsed = $parsed->unparse(
+ APR::Const::URI_UNP_OMITQUERY|APR::Const::URI_UNP_OMITPASSWORD);
+ my $url2 = sprintf "%s://%s\@%s%s", map { $url{$_}[1] }
+ grep !/^(password|port|query|fragment)$/, @keys_urls;
+ ok t_cmp($url_unparsed, $url2, "unparsed url: omit query");
+ }
+ }
+
+ ### port_of_scheme ###
+ while (my ($scheme, $port) = each %default_ports) {
+ my $apr_port = APR::URI::port_of_scheme($scheme);
+ ok t_cmp($apr_port, $port, "scheme: $scheme");
+ }
+
+ # parse + out-of-scope pools
+ {
+
+ my $url0 = sprintf "%s://%s:%s\@%s:%d%s?%s#%s",
+ map { $url{$_}[0] } @keys_urls;
+ # warn "URL: $url\n";
+ my $hostinfo0 = sprintf "%s:%s\@%s:%d",
+ map { $url{$_}[0] } @keys_hostinfo;
+
+ require APR::Pool;
+ my $parsed = APR::URI->parse(APR::Pool->new, $url0);
+
+ # try to overwrite the temp pool data
+ require APR::Table;
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+
+ for my $method (keys %url) {
+ no strict 'refs';
+ ok t_cmp($parsed->$method, $url{$method}[0], $method);
+ }
+
+ ok t_cmp($parsed->hostinfo, $hostinfo0, "hostinfo");
+ }
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/util.pm b/2_0_13/t/lib/TestAPRlib/util.pm
new file mode 100644
index 0000000..cd5f761
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/util.pm
@@ -0,0 +1,57 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::util;
+
+# test APR::Util
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Util ();
+
+use constant CRYPT_WORKS => $^O !~ /^(MSWin32|beos|NetWare)$/;
+
+my $clear = "this is some text";
+# to get the hash values used:
+# htpasswd -nb[sm] user "this is some text"
+my %hashes = (
+ crypt => 'pHM3JfnL6isho',
+ md5 => '$apr1$Kld6H/..$o5OPPPWslI3zB20S54u9s1',
+ sha1 => '{SHA}A5NpTRa4TethLkfOYlK9NfDYbAY=',
+);
+
+# BACK_COMPAT_MARKER (sha1 support added in 2.0.50)
+delete $hashes{sha1} unless have_min_apache_version('2.0.50');
+
+sub num_of_tests {
+ return 1 + scalar keys %hashes;
+}
+
+sub test {
+
+ # password_validate
+ {
+ ok ! APR::Util::password_validate("one", "two");
+
+ while (my ($mode, $hash) = each %hashes) {
+ t_debug($mode);
+ if ($mode eq 'crypt' && !CRYPT_WORKS) {
+ t_debug("crypt is not supported on $^O");
+ ok 1; # don't make noise
+ }
+ else {
+ ok APR::Util::password_validate($clear, $hash);
+ }
+ }
+ }
+
+#this function seems unstable on certain platforms
+# my $blen = 10;
+# my $bytes = APR::generate_random_bytes($blen);
+# ok length($bytes) == $blen;
+
+}
+
+1;
diff --git a/2_0_13/t/lib/TestAPRlib/uuid.pm b/2_0_13/t/lib/TestAPRlib/uuid.pm
new file mode 100644
index 0000000..8942c79
--- /dev/null
+++ b/2_0_13/t/lib/TestAPRlib/uuid.pm
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPRlib::uuid;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+my $dummy_uuid = 'd48889bb-d11d-b211-8567-ec81968c93c6';
+
+require APR;
+require APR::UUID;
+
+#XXX: apr_generate_random_bytes may block forever on /dev/random
+# my $uuid = APR::UUID->new->format;
+
+sub num_of_tests {
+ return 3;
+}
+
+sub test {
+ my $uuid = $dummy_uuid;
+
+ ok $uuid;
+
+ my $uuid_parsed = APR::UUID->parse($uuid);
+
+ ok $uuid_parsed;
+
+ ok $uuid eq $uuid_parsed->format;
+}
+
+1;
diff --git a/2_0_13/t/lib/TestCommon/FilterDebug.pm b/2_0_13/t/lib/TestCommon/FilterDebug.pm
new file mode 100644
index 0000000..8836f15
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/FilterDebug.pm
@@ -0,0 +1,82 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::FilterDebug;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw(Apache2::Filter);
+use APR::Brigade ();
+use APR::Bucket ();
+use APR::BucketType ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+use APR::Const -compile => ':common';
+
+# to use these functions add any or all of these filter handlers
+# PerlModule TestCommon::FilterDebug
+# PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
+# PerlInputFilterHandler TestCommon::FilterDebug::snoop_connection
+# PerlOutputFilterHandler TestCommon::FilterDebug::snoop_request
+# PerlOutputFilterHandler TestCommon::FilterDebug::snoop_connection
+#
+
+sub snoop_connection : FilterConnectionHandler { snoop("connection", @_) }
+sub snoop_request : FilterRequestHandler { snoop("request", @_) }
+
+sub snoop {
+ my $type = shift;
+ my ($filter, $bb, $mode, $block, $readbytes) = @_; # filter args
+
+ # $mode, $block, $readbytes are passed only for input filters
+ my $stream = defined $mode ? "input" : "output";
+
+ # read the data and pass-through the bucket brigades unchanged
+ if (defined $mode) {
+ # input filter
+ my $rv = $filter->next->get_brigade($bb, $mode, $block, $readbytes);
+ return $rv unless $rv == APR::Const::SUCCESS;
+ bb_dump($type, $stream, $bb);
+ }
+ else {
+ # output filter
+ bb_dump($type, $stream, $bb);
+ my $rv = $filter->next->pass_brigade($bb);
+ return $rv unless $rv == APR::Const::SUCCESS;
+ }
+ #if ($bb->is_empty) {
+ # return -1;
+ #}
+
+ return Apache2::Const::OK;
+}
+
+sub bb_dump {
+ my ($type, $stream, $bb) = @_;
+
+ my @data;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ $b->read(my $bdata);
+ push @data, $b->type->name, $bdata;
+ }
+
+ # send the sniffed info to STDERR so not to interfere with normal
+ # output
+ my $direction = $stream eq 'output' ? ">>>" : "<<<";
+ print STDERR "\n$direction $type $stream filter\n";
+
+ unless (@data) {
+ print STDERR " No buckets\n";
+ return;
+ }
+
+ my $c = 1;
+ while (my ($btype, $data) = splice @data, 0, 2) {
+ print STDERR " o bucket $c: $btype\n";
+ print STDERR "[$data]\n";
+ $c++;
+ }
+}
+
+1;
+
+__END__
diff --git a/2_0_13/t/lib/TestCommon/Handlers.pm b/2_0_13/t/lib/TestCommon/Handlers.pm
new file mode 100644
index 0000000..de7bf33
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/Handlers.pm
@@ -0,0 +1,62 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::Handlers;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use TestCommon::Utils ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(M_POST OK);
+
+# read the posted body and send it back to the client as is
+sub pass_through_response_handler {
+ my $r = shift;
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $data = TestCommon::Utils::read_post($r);
+ debug "pass_through_handler read: $data\n";
+ $r->print($data);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+TestCommon::Handlers - Common Handlers
+
+
+
+=head1 Synopsis
+
+ # PerlModule TestCommon::Handlers
+ # PerlResponseHandler TestCommon::Handlers::pass_through_response_handler
+
+
+=head1 Description
+
+Various commonly used handlers
+
+
+
+
+=head1 API
+
+=head2 pass_through_response_handler
+
+ # PerlModule TestCommon::Handlers
+ # PerlResponseHandler TestCommon::Handlers::pass_through_response_handler
+
+this is a response handler, which reads the posted body and sends it
+back to the client as is.
+
+=cut
diff --git a/2_0_13/t/lib/TestCommon/LogDiff.pm b/2_0_13/t/lib/TestCommon/LogDiff.pm
new file mode 100644
index 0000000..36b8314
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/LogDiff.pm
@@ -0,0 +1,94 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::LogDiff;
+
+use strict;
+use warnings FATAL => 'all';
+
+use POSIX ();
+
+sub new {
+ my $class = shift;
+ my $path = shift;
+
+ open my $fh, "<$path" or die "Can't open $path: $!";
+ seek $fh, 0, POSIX::SEEK_END();
+ my $pos = tell $fh;
+
+ my %self = (
+ path => $path,
+ fh => $fh,
+ pos => $pos,
+ );
+
+ return bless \%self, $class;
+}
+
+sub DESTROY {
+ my $self = shift;
+ close $self->{fh};
+}
+
+sub diff {
+ my $self = shift;
+
+ # XXX: is it possible that some system will be slow to flush the
+ # buffers and we may need to wait a bit and retry if we see no new
+ # logged data?
+ my $fh = $self->{fh};
+ seek $fh, $self->{pos}, POSIX::SEEK_SET(); # not really needed
+
+ local $/; # slurp mode
+ my $diff = <$fh>;
+ seek $fh, 0, POSIX::SEEK_END();
+ $self->{pos} = tell $fh;
+
+ return defined $diff ? $diff : '';
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+TestCommon::LogDiff - get log file diffs
+
+=head1 Synopsis
+
+ use TestCommon::LogDiff;
+ use Apache::Test;
+
+ plan tests => 2;
+
+ my $path = "/tmp/mylog";
+ open my $fh, ">>$path" or die "Can't open $path: $!";
+
+ my $logdiff = TestCommon::LogDiff->new($path);
+
+ print $fh "foo 123\n";
+ my $expected = qr/^foo/;
+ ok t_cmp $logdiff->diff, $expected;
+
+ print $fh "bar\n";
+ my $expected = 'bar';
+ ok t_cmp $logdiff->diff, $expected;
+
+
+=head1 Description
+
+Useful for testing the warning, error and other messages going into
+the log file.
+
+=head1 API
+
+=head2 new
+
+open the log file and point the filehandle pointer to its end.
+
+=head2 diff
+
+extract any newly logged information since the last check and move the
+filehandle to the end of the file.
+
+=cut
+
diff --git a/2_0_13/t/lib/TestCommon/MemoryLeak.pm b/2_0_13/t/lib/TestCommon/MemoryLeak.pm
new file mode 100644
index 0000000..c007005
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/MemoryLeak.pm
@@ -0,0 +1,88 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::MemoryLeak;
+
+# handy functions to measure memory leaks. since it measures the total
+# memory size of the process and not just perl leaks, you get your
+# C/XS leaks discovered too
+#
+# For example to test TestAPR::Pool::handler for leaks, add to its
+# top:
+#
+# TestCommon::MemoryLeak::start();
+#
+# and just before returning from the handler add:
+#
+# TestCommon::MemoryLeak::end();
+#
+# now start the server with only worker server
+#
+# % t/TEST -maxclients 1 -start
+#
+# of course use maxclients 1 only if your test be handled with one
+# client, e.g. proxy tests need at least two clients.
+#
+# Now repeat the same test several times (more than 3)
+#
+# % t/TEST -run apr/pool -times=10
+#
+# t/logs/error_log will include something like:
+#
+# size vsize resident share rss
+# 196k 132k 196k 0M 196k
+# 104k 132k 104k 0M 104k
+# 16k 0k 16k 0k 16k
+# 0k 0k 0k 0k 0k
+# 0k 0k 0k 0k 0k
+# 0k 0k 0k 0k 0k
+#
+# as you can see the first few runs were allocating memory, but the
+# following runs should consume no more memory. The leak tester measures
+# the extra memory allocated by the process since the last test. Notice
+# that perl and apr pools usually allocate more memory than they
+# need, so some leaks can be hard to see, unless many tests (like a
+# hundred) were run.
+
+use strict;
+use warnings FATAL => 'all';
+
+# XXX: as of 5.8.4 when spawning ithreads we get an annoying
+# Attempt to free unreferenced scalar ... perlbug #24660
+# because of $gtop's CLONE'd object, so pretend that we have no gtop
+# for now if perl is threaded
+# GTop v0.12 is the first version that will work under threaded mpms
+use Config;
+use constant HAS_GTOP => eval { !$Config{useithreads} &&
+ require GTop && GTop->VERSION >= 0.12 };
+
+my $gtop = HAS_GTOP ? GTop->new : undef;
+my @attrs = qw(size vsize resident share rss);
+my $format = "%8s %8s %8s %8s %8s\n";
+
+my %before;
+
+sub start {
+
+ die "No GTop avaible, bailing out" unless HAS_GTOP;
+
+ unless (keys %before) {
+ my $before = $gtop->proc_mem($$);
+ %before = map { $_ => $before->$_() } @attrs;
+ # print the header once
+ warn sprintf $format, @attrs;
+ }
+}
+
+sub end {
+
+ die "No GTop avaible, bailing out" unless HAS_GTOP;
+
+ my $after = $gtop->proc_mem($$);
+ my %after = map {$_ => $after->$_()} @attrs;
+ warn sprintf $format,
+ map GTop::size_string($after{$_} - $before{$_}), @attrs;
+ %before = %after;
+}
+
+1;
+
+__END__
diff --git a/2_0_13/t/lib/TestCommon/SameInterp.pm b/2_0_13/t/lib/TestCommon/SameInterp.pm
new file mode 100644
index 0000000..ad7a01d
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/SameInterp.pm
@@ -0,0 +1,166 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::SameInterp;
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Exporter;
+use vars qw(@ISA @EXPORT);
+
+@ISA = qw(Exporter);
+
+@EXPORT = qw(same_interp_req same_interp_req_body
+ same_interp_skip_not_found);
+
+sub same_interp_req {
+ my $res = eval {
+ Apache::TestRequest::same_interp_do(@_);
+ };
+ return undef if $@ && $@ =~ /unable to find interp/;
+ die $@ if $@;
+ return $res;
+}
+
+sub same_interp_req_body {
+ my $res = same_interp_req(@_);
+ return $res ? $res->content : "";
+}
+
+sub same_interp_skip_not_found {
+ my $skip_cond = shift;
+ if ($skip_cond) {
+ skip "Skip couldn't find the same interpreter", 0;
+ }
+ else {
+ my ($package, $filename, $line) = caller;
+ # trick ok() into reporting the caller filename/line when a
+ # sub-test fails in sok()
+ return eval <<EOE;
+#line $line $filename
+ ok &t_cmp;
+EOE
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+TestCommon::SameInterp - Helper functions for same_interp framework
+
+=head1 Synopsis
+
+ use Apache::Test;
+ use Apache::TestUtil;
+ use Apache::TestRequest;
+
+ use TestCommon::SameInterp;
+
+ plan tests => 3;
+
+ my $url = "/path";
+
+ my $same_interp = Apache::TestRequest::same_interp_tie($url);
+ ok $same_interp;
+
+ my $expected = 1;
+ my $skip = 0;
+ # test GET over the same same_interp
+ for (1..2) {
+ $expected++;
+ my $res = same_interp_req($same_interp, \&GET, $url, foo => 'bar');
+ $skip++ unless defined $res;
+ same_interp_skip_not_found(
+ $skip,
+ defined $res && $res->content,
+ $expected,
+ "GET over the same interp"
+ );
+ }
+
+
+=head1 Description
+
+In addition to same_interp base blocks from Apache::TestRequest, this
+helper module provides extra wrappers to simplify the writing of tests
+
+META: consider merging those into Apache::TestRequest (or add a new
+module, e.g. Apache::TestRequestSameInterp)
+
+=head1 API
+
+
+
+=head2 C<same_interp_req>
+
+normally one runs:
+
+ my $res = GET $url, @data;
+
+in the same_interp framework one runs
+
+ my $res = Apache::TestRequest::same_interp_do($same_interp,
+ \&GET, $url, @data);
+
+but if there is a failure to find the same interpreter we get an
+exception. and there could be other exceptions as well (e.g. failure
+to run the request). This wrapper handles all exceptions, returning
+C<undef> if the exception was in a failure to find the same
+interpreter, re-throws the exception otherwise. If there is no
+exception, the response object is returned.
+
+So one passes the same arguments to this wrapper as you'd to
+Apache::TestRequest::same_interp_do:
+
+ my $res = same_interp_req($same_interp, \&GET, $url, @data);
+
+
+
+=head2 C<same_interp_req_body>
+
+This function calls C<L<same_interp_req|/C_same_interp_req_>> and
+extracts the response body if the response object is defined. (sort of
+GET_BODY for same_interp)
+
+
+=head2 C<same_interp_skip_not_found>
+
+make the tests resistant to a failure of finding the same perl
+interpreter, which happens randomly and not an error. so instead of running:
+
+ my $res = same_interp_req($same_interp, \&GET, $url, @data);
+ ok t_cmp(defined $res && $res->content, $expected, "comment")
+
+one can run:
+
+ my $res = same_interp_req($same_interp, \&GET, $url, @data);
+ $skip = defined $res ? 0 : 1;
+ same_interp_skip_not_found(
+ $skip,
+ defined $res && $res->content,
+ $expected,
+ "comment"
+ );
+
+the first argument is used to decide whether to skip the sub-test, the
+rest of the arguments are passed to 'ok t_cmp'.
+
+This wrapper is smart enough to report the correct line number as if
+ok() was run in the test file itself and not in the wrapper, by doing:
+
+ my ($package, $filename, $line) = caller;
+ return eval <<EOE;
+ #line $line $filename
+ ok &t_cmp;
+ EOE
+
+C<&t_cmp> receives C<@_>, containing all but the skip argument, as if
+the wrapper was never called.
+
+
+
+
+=cut
+
diff --git a/2_0_13/t/lib/TestCommon/TiePerlSection.pm b/2_0_13/t/lib/TestCommon/TiePerlSection.pm
new file mode 100644
index 0000000..e7c0780
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/TiePerlSection.pm
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::TiePerlSection;
+
+use strict;
+use warnings FATAL => 'all';
+
+# the following is needed for the tied %Location test in <Perl>
+# sections. Unfortunately it can't be defined in the section itself
+# due to the bug in perl:
+# http://rt.perl.org:80/rt3/Ticket/Display.html?id=29018
+
+use Tie::Hash;
+our @ISA = qw(Tie::StdHash);
+sub FETCH {
+ my ($hash, $key) = @_;
+ if ($key eq '/tied') {
+ return 'TIED';
+ }
+ return $hash->{$key};
+}
+
+1;
diff --git a/2_0_13/t/lib/TestCommon/Utils.pm b/2_0_13/t/lib/TestCommon/Utils.pm
new file mode 100644
index 0000000..672c439
--- /dev/null
+++ b/2_0_13/t/lib/TestCommon/Utils.pm
@@ -0,0 +1,122 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCommon::Utils;
+
+use strict;
+use warnings FATAL => 'all';
+
+use APR::Brigade ();
+use APR::Bucket ();
+use Apache2::Filter ();
+use Apache2::Connection ();
+
+use Apache2::Const -compile => qw(MODE_READBYTES);
+use APR::Const -compile => qw(SUCCESS BLOCK_READ);
+
+use constant IOBUFSIZE => 8192;
+
+# perl 5.6.x only triggers taint protection on strings which are at
+# least one char long
+sub is_tainted {
+ return ! eval {
+ eval join '', '#',
+ map defined() ? substr($_, 0, 0) : (), @_;
+ 1;
+ };
+}
+
+# to enable debug start with: (or simply run with -trace=debug)
+# t/TEST -trace=debug -start
+sub read_post {
+ my $r = shift;
+ my $debug = shift || 0;
+
+ my $bb = APR::Brigade->new($r->pool,
+ $r->connection->bucket_alloc);
+
+ my $data = '';
+ my $seen_eos = 0;
+ my $count = 0;
+ do {
+ $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
+ APR::Const::BLOCK_READ, IOBUFSIZE);
+
+ $count++;
+
+ warn "read_post: bb $count\n" if $debug;
+
+ while (!$bb->is_empty) {
+ my $b = $bb->first;
+
+ if ($b->is_eos) {
+ warn "read_post: EOS bucket:\n" if $debug;
+ $seen_eos++;
+ last;
+ }
+
+ if ($b->read(my $buf)) {
+ warn "read_post: DATA bucket: [$buf]\n" if $debug;
+ $data .= $buf;
+ }
+
+ $b->delete;
+ }
+
+ } while (!$seen_eos);
+
+ $bb->destroy;
+
+ return $data;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+TestCommon::Utils - Common Test Utils
+
+
+
+=head1 Synopsis
+
+ use TestCommon::Utils;
+
+ # test whether some SV is tainted
+ $b->read(my $data);
+ ok TestCommon::Utils::is_tainted($data);
+
+ my $data = TestCommon::Utils::read_post($r);
+
+=head1 Description
+
+Various handy testing utils
+
+
+
+
+=head1 API
+
+
+
+=head2 is_tainted
+
+ is_tainted(@data);
+
+returns I<TRUE> if at least one element in C<@data> is tainted,
+I<FALSE> otherwise.
+
+
+
+=head2 read_post
+
+ my $data = TestCommon::Utils::read_post($r);
+ my $data = TestCommon::Utils::read_post($r, $debug);
+
+reads the posted data using bucket brigades manipulation.
+
+To enable debug pass a true argument C<$debug>
+
+
+=cut
+
diff --git a/2_0_13/t/lib/TestExit/FromPerlModule.pm b/2_0_13/t/lib/TestExit/FromPerlModule.pm
new file mode 100644
index 0000000..774c281
--- /dev/null
+++ b/2_0_13/t/lib/TestExit/FromPerlModule.pm
@@ -0,0 +1,22 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestExit::FromPerlModule;
+
+use strict;
+use warnings FATAL => qw(all);
+
+use Apache2::ServerRec;
+use Apache2::ServerUtil;
+use Apache2::Log;
+use Apache2::Const -compile => qw(OK);
+
+sub exit_handler {
+ my ($p, $s) = @_;
+
+ $s->log->info("Child process pid=$$ is exiting - server push");
+
+ Apache2::Const::OK;
+}
+
+Apache2::ServerUtil->server->push_handlers(PerlChildExitHandler => \&exit_handler);
+
+1;
diff --git a/2_0_13/t/modperl/cookie.t b/2_0_13/t/modperl/cookie.t
new file mode 100644
index 0000000..13d275b
--- /dev/null
+++ b/2_0_13/t/modperl/cookie.t
@@ -0,0 +1,58 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# The Cookie HTTP header can be accessed via $r->headers_in and in certain
+# situations via $ENV{HTTP_COOKIE}.
+#
+# 'SetHandler perl-script', combined with 'PerlOptions -SetupEnv', or
+# 'SetHandler modperl' do not populate %ENV with CGI variables. So in
+# this test we call $r->subprocess_env, which adds them on demand, and
+# we are able to get the cookie via %ENV.
+#
+# the last sub-test makes sure that mod_cgi env vars don't persist
+# and are properly re-set at the end of each request.
+#
+# since the test is run against the same interpreter we also test that
+# the cookie value doesn't persist if it makes it to %ENV.
+
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+Apache::TestRequest::user_agent(keep_alive => 1);
+
+plan tests => 3, need 'HTML::HeadParser';
+
+my $module = 'TestModperl::cookie';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+my $cookie = 'foo=bar';
+my %cookies = (
+ header => $cookie,
+ env => $cookie,
+ nocookie => '',
+);
+
+# 'nocookie' must be run last, server-side shouldn't find a cookie
+# (testing that %ENV is reset to its original values for vars set by
+# $r->subprocess_env, which is run internally for 'perl-script')
+# this requires that all the tests are run against the same interpter
+
+my @tests_ordered = qw(header env nocookie);
+
+GET $location;
+
+for my $test (@tests_ordered) {
+ my $expected = $test eq 'nocookie' ? '' : "bar";
+ my @headers = ();
+ push @headers, (Cookie => $cookies{$test}) unless $test eq 'nocookie';
+
+ my $received = GET "$location?$test", @headers;
+
+ ok t_cmp(
+ $received->content,
+ $expected,
+ "perl-script+SetupEnv/cookie: $test"
+ );
+}
diff --git a/2_0_13/t/modperl/cookie2.t b/2_0_13/t/modperl/cookie2.t
new file mode 100644
index 0000000..e49ae21
--- /dev/null
+++ b/2_0_13/t/modperl/cookie2.t
@@ -0,0 +1,44 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+# The Cookie HTTP header can be accessed via $r->headers_in and in certain
+# situations via $ENV{HTTP_COOKIE}.
+#
+# in this test we shouldn't be able get the cookie via %ENV,
+# since 'SetHandler modperl' doesn't set up CGI env var. unless the
+# handler calls "$r->subprocess_env" by itself
+#
+# since the test is run against the same interpreter we also test that
+# the cookie value doesn't persist if it makes it to %ENV.
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+Apache::TestRequest::user_agent(keep_alive => 1);
+
+plan tests => 3, need 'HTML::HeadParser';
+
+my $module = 'TestModperl::cookie2';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+my %expected =
+(
+ header => "header",
+ subprocess_env => "subprocess_env",
+ env => '',
+);
+
+my @tests_ordered = qw(header subprocess_env env);
+
+for my $test (@tests_ordered) {
+ my $cookie = "key=$test";
+
+ my $received = GET "$location?$test", Cookie => $cookie;
+
+ ok t_cmp(
+ $received->content,
+ $expected{$test},
+ "perl-script+SetupEnv/cookie: $test",
+ );
+}
diff --git a/2_0_13/t/modperl/exit.t b/2_0_13/t/modperl/exit.t
new file mode 100644
index 0000000..b519d7a
--- /dev/null
+++ b/2_0_13/t/modperl/exit.t
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use ModPerl::Const -compile => 'EXIT';
+
+my $location = "/TestModperl__exit";
+
+plan tests => 3;
+
+{
+ ok t_cmp(GET_BODY_ASSERT("$location?noneval"),
+ 'exited',
+ "exit in non eval context");
+
+}
+{
+ my $exit_excpt = ModPerl::EXIT;
+ my $body = GET_BODY_ASSERT("$location?eval");
+ ok t_cmp($body,
+ qr/^ModPerl::Util::exit: \($exit_excpt\) exit was called/,
+ "exit in eval context");
+
+ ok !t_cmp($body,
+ qr/must not be reached/,
+ "exit in eval context");
+
+}
diff --git a/2_0_13/t/modperl/getc.t b/2_0_13/t/modperl/getc.t
new file mode 100644
index 0000000..62763f1
--- /dev/null
+++ b/2_0_13/t/modperl/getc.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 2;
+
+my $location = "/TestModperl__getc";
+
+my $expect = join '', 'a'..'Z';
+
+my $str = POST_BODY $location, content => $expect;
+
+ok $str;
+
+ok t_cmp($str, $expect, 'getc');
+
diff --git a/2_0_13/t/modperl/local_env.t b/2_0_13/t/modperl/local_env.t
new file mode 100644
index 0000000..7aeb728
--- /dev/null
+++ b/2_0_13/t/modperl/local_env.t
@@ -0,0 +1,15 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+plan tests => 1, skip_reason('local %ENV is still broken');
+
+my $module = 'TestModperl::local_env';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug "connecting to $url";
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/merge.t b/2_0_13/t/modperl/merge.t
new file mode 100644
index 0000000..9e1a5cd
--- /dev/null
+++ b/2_0_13/t/modperl/merge.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestModperl::merge';
+my $url = Apache::TestRequest::module2url($module, {path => '/merge/'});
+
+# test server-to-container merging (without overrides) for:
+# PerlSetEnv
+# PerlPassEnv
+# PerlSetVar
+# PerlAddVar
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/merge2.t b/2_0_13/t/modperl/merge2.t
new file mode 100644
index 0000000..4b64e49
--- /dev/null
+++ b/2_0_13/t/modperl/merge2.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestModperl::merge';
+my $url = Apache::TestRequest::module2url($module, {path => '/merge2/'});
+
+# test server-to-container merging (with overrides) for:
+# PerlSetEnv
+# PerlPassEnv
+# PerlSetVar
+# PerlAddVar
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/merge3.t b/2_0_13/t/modperl/merge3.t
new file mode 100644
index 0000000..b208f37
--- /dev/null
+++ b/2_0_13/t/modperl/merge3.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestModperl::merge';
+my $url = Apache::TestRequest::module2url($module, {path => '/merge3/'});
+
+# test multi-level merging (server-to-container-to-htaccess) for:
+# PerlSetEnv
+# PerlPassEnv
+# PerlSetVar
+# PerlAddVar
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/perl_options.t b/2_0_13/t/modperl/perl_options.t
new file mode 100644
index 0000000..9d99cb3
--- /dev/null
+++ b/2_0_13/t/modperl/perl_options.t
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = 'TestModperl::perl_options';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug "connecting to $url";
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/perl_options2.t b/2_0_13/t/modperl/perl_options2.t
new file mode 100644
index 0000000..9223b30
--- /dev/null
+++ b/2_0_13/t/modperl/perl_options2.t
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = 'TestModperl::perl_options2';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug "connecting to $url";
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/pnotes.t b/2_0_13/t/modperl/pnotes.t
new file mode 100644
index 0000000..3ef4b37
--- /dev/null
+++ b/2_0_13/t/modperl/pnotes.t
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestModperl::pnotes';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+
+plan tests => (26 * 3), need_lwp;
+
+# first with keepalives
+Apache::TestRequest::user_agent(reset => 1, keep_alive => 1);
+t_debug("issuing first request");
+print GET_BODY_ASSERT "$url?1";
+
+# now close the connection
+t_debug("issuing second request");
+print GET_BODY_ASSERT "$url?2", Connection => 'close';
+
+# finally, check for a cleared $c->pnotes
+t_debug("issuing final request");
+print GET_BODY_ASSERT "$url?3";
+
diff --git a/2_0_13/t/modperl/pnotes2.t b/2_0_13/t/modperl/pnotes2.t
new file mode 100644
index 0000000..87f752a
--- /dev/null
+++ b/2_0_13/t/modperl/pnotes2.t
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY);
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestUtil qw/t_start_error_log_watch t_finish_error_log_watch/;
+
+my $module = 'TestModperl::pnotes2';
+my $url = Apache::TestRequest::module2url($module);
+my ($u, $ok);
+
+t_debug("connecting to $url");
+
+plan tests => 12, need_lwp;
+
+Apache::TestRequest::user_agent(reset => 1, keep_alive => 0);
+
+for my $i (1..12) {
+ t_client_log_warn_is_expected();
+ t_start_error_log_watch;
+ $u="$url?$i"; $ok=GET_BODY $u;
+ select undef, undef, undef, 0.2; # give it time to write the logfile
+ ok t_cmp scalar(grep {
+ /pnotes are destroyed after cleanup passed/;
+ } t_finish_error_log_watch), 1, $u;
+}
diff --git a/2_0_13/t/modperl/post_utf8.t b/2_0_13/t/modperl/post_utf8.t
new file mode 100644
index 0000000..83e6b28
--- /dev/null
+++ b/2_0_13/t/modperl/post_utf8.t
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+
+my $location = "/TestModperl__post_utf8";
+
+# From A.S.Pushkin's "Evgeniy Onegin"
+my $data_ascii = "I love you, (why lying?), but I belong to another";
+my $data_utf8 = "\x{042F} \x{0432}\x{0430}\x{0441} \x{043B}\x{044E}" .
+ "\x{0431}\x{043B}\x{044E} (\x{043A} \x{0447}\x{0435}\x{043C}\x{0443} " .
+ "\x{043B}\x{0443}\x{043A}\x{0430}\x{0432}\x{0438}\x{0442}\x{044C}?),\n" .
+ "\x{041D}\x{043E} \x{044F} \x{0434}\x{0440}\x{0443}\x{0433}\x{043E}" .
+ "\x{043C}\x{0443} \x{043E}\x{0442}\x{0434}\x{0430}\x{043D}\x{0430};";
+
+my $data = join '=', $data_ascii, $data_utf8;
+
+# must encode the utf8 request body
+# we will skip the response any way if perl < 5.008
+utf8::encode($data) if $] >= 5.008;
+
+# Accept-Charset is not really needed, since we don't expect the
+# server side to send anything back but plain ASCII.
+print POST_BODY_ASSERT $location, content => $data,
+ 'Accept-Charset' => "ISO-8859-1,UTF-8";
+
+
diff --git a/2_0_13/t/modperl/print_utf8.t b/2_0_13/t/modperl/print_utf8.t
new file mode 100644
index 0000000..d29d543
--- /dev/null
+++ b/2_0_13/t/modperl/print_utf8.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+# utf encode/decode was added only in 5.8.0
+# XXX: currently binmode is only available with perlio (used on the
+# server side on the tied/perlio STDOUT)
+plan tests => 1, need need_min_perl_version(5.008), need_perl('perlio');
+
+my $location = "/TestModperl__print_utf8";
+my $expected = "Hello Ayhan \x{263A} perlio rules!";
+
+my $res = GET $location;
+my $received = $res->content;
+
+# response body includes wide-chars, but perl doesn't know about it
+utf8::decode($received) if ($res->header('Content-Type')||'') =~ /utf-8/i;
+
+# needed for debugging print out of utf8 strings
+binmode(STDOUT, ':utf8');
+ok t_cmp($received, $expected, 'UTF8 response via tied/perlio STDOUT');
+
diff --git a/2_0_13/t/modperl/print_utf8_2.t b/2_0_13/t/modperl/print_utf8_2.t
new file mode 100644
index 0000000..9a12dd2
--- /dev/null
+++ b/2_0_13/t/modperl/print_utf8_2.t
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+use Config;
+
+# utf encode/decode was added only in 5.8.0
+# perlio is needed only for the client side, because it calls binmode(STDOUT, ':utf8');
+plan tests => 1, need_min_perl_version(5.008);
+
+my $location = "/TestModperl__print_utf8_2";
+my $expected = "\$r->print() just works \x{263A}";
+
+my $res = GET $location;
+my $received = $res->content;
+
+# response body includes wide-chars, but perl doesn't know about it
+utf8::decode($received) if ($res->header('Content-Type')||'') =~ /utf-8/i;
+
+if ($Config{useperlio}) {
+ # needed for debugging print out of utf8 strings
+ # but works only if perl is built w/ perlio
+ binmode(STDOUT, ':utf8');
+ ok t_cmp($received, $expected, 'UTF8 response via $r->print');
+}
+else {
+ ok $expected eq $received;
+}
+
diff --git a/2_0_13/t/modperl/readline.t b/2_0_13/t/modperl/readline.t
new file mode 100644
index 0000000..11b4cb7
--- /dev/null
+++ b/2_0_13/t/modperl/readline.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 2;
+
+my $location = "/TestModperl__readline";
+
+my $expect = join "\n", map { $_ x 24 } 'a'..'e';
+
+my $str = POST_BODY $location, content => $expect;
+
+ok $str;
+
+ok t_cmp($str, $expect, 'readline');
+
diff --git a/2_0_13/t/modperl/request_rec_perlio_api.t b/2_0_13/t/modperl/request_rec_perlio_api.t
new file mode 100644
index 0000000..2801ddc
--- /dev/null
+++ b/2_0_13/t/modperl/request_rec_perlio_api.t
@@ -0,0 +1,30 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use Config;
+
+my $uri = "/TestModperl__request_rec_perlio_api";
+
+plan tests => 2, need { "perl $]: TIEd IO is used instead of PerlIO"
+ => ($] >= 5.008 && $Config{useperlio}) };
+
+
+{
+ my $content = join "", 'a'..'j', 'k'..'t';
+ my $location = "$uri?STDIN";
+ my $expected = join "", 'a'..'j', "# please", 'k'..'t';
+ my $received = POST_BODY_ASSERT $location, content => $content;
+ ok t_cmp($received, $expected, "STDIN tests");
+}
+
+{
+ my $location = "$uri?STDOUT";
+ my $expected = "life is hard and then you die! next you reincarnate...";
+ my $received = GET_BODY_ASSERT $location;
+ ok t_cmp($received, $expected, "STDOUT tests");
+}
diff --git a/2_0_13/t/modperl/setupenv.t b/2_0_13/t/modperl/setupenv.t
new file mode 100644
index 0000000..a4611f6
--- /dev/null
+++ b/2_0_13/t/modperl/setupenv.t
@@ -0,0 +1,47 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestModperl::setupenv';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+
+my @locations = ("${url}_mpdefault",
+ "${url}_mpsetup",
+ "${url}_mpdefault", # make sure %ENV is cleared
+ "${url}_mpvoid",
+ "${url}_mpsetupvoid",
+ "${url}_psdefault",
+ "${url}_psnosetup",
+ "${url}_psvoid",
+ "${url}_psnosetupvoid");
+
+# plan the tests from a handler so we can run
+# tests from within handlers across multiple requests
+#
+# this requires keepalives and a per-connection interpreter
+# to make certain we can plan in one request and test in another
+# which requires LWP
+unless (need_lwp() && need_module('mod_env')) {
+ plan tests => 63, 0;
+}
+
+Apache::TestRequest::user_agent(keep_alive => 1);
+print GET_BODY_ASSERT join '?', $url, scalar @locations;
+
+# this tests for when %ENV is populated with CGI variables
+# as well as the contents of the subprocess_env table
+#
+# see setupenv.pm for a full description of the tests
+
+foreach my $location (@locations) {
+
+ t_debug("trying $location");
+
+ print GET_BODY_ASSERT $location;
+}
diff --git a/2_0_13/t/modperl/setupenv2.t b/2_0_13/t/modperl/setupenv2.t
new file mode 100644
index 0000000..f8752b0
--- /dev/null
+++ b/2_0_13/t/modperl/setupenv2.t
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $location = "/TestModperl__setupenv2";
+
+my %expected = (
+ mixed => [qw(loadmodule conf1 <perl> conf2 require conf3
+ config_require conf4 perlmodule conf5 conf5
+ conf6 conf7 conf8 post_config_require)],
+ perl => [qw(loadmodule <perl> require config_require
+ perlmodule post_config_require)],
+);
+
+plan tests => 2 + scalar(@{ $expected{mixed} }) + scalar(@{ $expected{perl} });
+
+while (my ($k, $v) = each %expected) {
+ my @expected = @$v;
+ my $elements = scalar @expected;
+ my $received = GET_BODY "$location?$k";
+ t_debug "$k: $received";
+ my @received = split / /, $received;
+
+ ok t_cmp $received[$_], $expected[$_] for 0..$#expected;
+
+ ok t_cmp scalar(@received), scalar(@expected), "elements";
+ if (@received > @expected) {
+ t_debug "unexpected elements: " .
+ join " ", @received[$elements..$#received];
+ }
+}
+
diff --git a/2_0_13/t/modperl/status.t b/2_0_13/t/modperl/status.t
new file mode 100644
index 0000000..9cb8aba
--- /dev/null
+++ b/2_0_13/t/modperl/status.t
@@ -0,0 +1,158 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil qw(t_cmp t_server_log_error_is_expected);
+
+use Apache2::Const -compile => qw(OK DECLINED
+ NOT_FOUND SERVER_ERROR FORBIDDEN
+ HTTP_OK);
+
+plan tests => 15, need 'HTML::HeadParser';
+
+my $base = "/TestModperl__status";
+
+# valid Apache return codes
+{
+ my $uri = join '?', $base, Apache2::Const::OK;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::HTTP_OK,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, Apache2::Const::DECLINED;
+ my $code = GET_RC $uri;
+
+ # no Alias to map us to DocumentRoot
+ ok t_cmp($code,
+ Apache2::Const::NOT_FOUND,
+ $uri);
+}
+
+# standard HTTP status codes
+{
+ my $uri = join '?', $base, Apache2::Const::NOT_FOUND;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::NOT_FOUND,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, Apache2::Const::FORBIDDEN;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::FORBIDDEN,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, Apache2::Const::SERVER_ERROR;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::SERVER_ERROR,
+ $uri);
+}
+
+# apache translates non-HTTP codes into 500
+# see ap_index_of_response
+{
+ my $uri = join '?', $base, 601;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::SERVER_ERROR,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, 313;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::SERVER_ERROR,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, 1;
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::SERVER_ERROR,
+ $uri);
+}
+
+# HTTP_OK is treated as an error, since it's not
+# OK, DECLINED, or DONE. while apache's lookups
+# succeed so the 200 is propagated to the client,
+# there's an error beneath that 200 code.
+{
+ my $uri = join '?', $base, Apache2::Const::HTTP_OK;
+ my $response = GET $uri;
+
+ ok t_cmp($response->code,
+ Apache2::Const::HTTP_OK,
+ $uri);
+
+ ok t_cmp($response->content,
+ qr/server encountered an internal error/,
+ $uri);
+}
+
+# mod_perl-specific implementation tests
+{
+ # ModPerl::Util::exit - voids return OK
+ my $uri = join '?', $base, 'exit';
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::HTTP_OK,
+ $uri);
+}
+
+{
+ # die gets trapped
+ my $uri = join '?', $base, 'die';
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::SERVER_ERROR,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, 'foobar';
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::HTTP_OK,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, 'foo9bar';
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::HTTP_OK,
+ $uri);
+}
+
+{
+ my $uri = join '?', $base, 'undef';
+ my $code = GET_RC $uri;
+
+ ok t_cmp($code,
+ Apache2::Const::HTTP_OK,
+ $uri);
+}
+
diff --git a/2_0_13/t/modules/apache_resource.t b/2_0_13/t/modules/apache_resource.t
new file mode 100644
index 0000000..316365d
--- /dev/null
+++ b/2_0_13/t/modules/apache_resource.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1, need qw[BSD::Resource],
+ { "CGI.pm (2.93 or higher) or Apache2::Request is needed" =>
+ !!(eval { require CGI && $CGI::VERSION >= 2.93 } ||
+ eval { require Apache2::Request })};
+
+{
+ # Apache2::Status menu inserted by Apache::Resource
+ my $url = '/status/perl?rlimit';
+ my $body = GET_BODY_ASSERT $url;
+ ok $body =~ /RLIMIT_CPU/;
+}
+
+# more tests would be nice, but I'm not sure how to write those w/o
+# causing problems to the rest of the test suite.
+# we could enable $ENV{PERL_RLIMIT_DEFAULTS} = 1; before loading
+# Apache2::Resource, which sets certain default values (works for me)
+# but it's not guaranteed that it'll work for others (since it's very
+# OS specific)
diff --git a/2_0_13/t/modules/apache_status.t b/2_0_13/t/modules/apache_status.t
new file mode 100644
index 0000000..5d07703
--- /dev/null
+++ b/2_0_13/t/modules/apache_status.t
@@ -0,0 +1,50 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+my $base_url = '/status/perl';
+
+my @opts = qw(script myconfig rgysubs section_config env isa_tree
+ symdump inc inh_tree sig);
+
+plan tests => @opts + 5, need 'HTML::HeadParser',
+ { "CGI.pm (2.93 or higher) or Apache2::Request is needed" =>
+ !!(eval { require CGI && $CGI::VERSION >= 2.93 } ||
+ eval { require Apache2::Request })};
+
+{
+ my $url = "$base_url";
+ my $body = GET_BODY_ASSERT $url;
+ # expecting: Embedded Perl version <b>v5.8.2</b> for ...
+ my $pver = $^V ? sprintf "v%vd", $^V : $];
+ ok t_cmp($body, qr[Embedded Perl version <b>$pver</b> for]);
+ # menu_item, part 1
+ # expecting: Test Entry
+ ok $body =~ /Test Menu Entry/;
+}
+
+{
+ # menu_item, part 2
+ my $url = "$base_url?test_menu";
+ my $body = GET_BODY_ASSERT $url;
+ ok $body =~ /This is just a test entry/;
+}
+
+for my $opt (@opts) {
+ my $url = "$base_url?$opt";
+ ok GET_BODY_ASSERT $url;
+}
+
+# B::Terse has an issue with XS, but Apache::Status shouldn't crash on
+# that
+{
+ # Syntax Tree Dump: syntax and execution order options
+ for (qw(slow exec)) {
+ my $url = "$base_url/$_/Apache2::Const::OK?noh_b_terse";
+ ok GET_OK $url;
+ }
+}
diff --git a/2_0_13/t/modules/cgi.t b/2_0_13/t/modules/cgi.t
new file mode 100644
index 0000000..0445d8e
--- /dev/null
+++ b/2_0_13/t/modules/cgi.t
@@ -0,0 +1,61 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache2::Build ();
+
+my $build = Apache2::Build->build_config;
+
+use constant HAVE_LWP => have_lwp();
+
+my $tests = 4;
+$tests += 1 if HAVE_LWP;
+
+plan tests => $tests, need need_min_module_version('CGI', 3.08),
+ {"MP_COMPAT_1X is disabled" => $build->{MP_COMPAT_1X}};
+
+my $module = 'TestModules::cgi';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+my($res, $str);
+
+sok {
+ my $url = "$location?PARAM=2";
+ $res = GET $url;
+ $str = $res->content;
+ t_cmp($str, "ok 2", "GET $url");
+};
+
+sok {
+ my $content = 'PARAM=%33';
+ $str = POST_BODY $location, content => $content;
+ t_cmp($str, "ok 3", "POST $location\n$content");
+};
+
+if (HAVE_LWP) {
+ sok {
+ t_client_log_warn_is_expected(4)
+ if $] < 5.008 && require CGI && $CGI::VERSION < 3.06;
+ $str = UPLOAD_BODY $location, content => 4;
+ t_cmp($str, "ok 4", 'file upload');
+ };
+}
+
+sok {
+ my $header = 'Content-type';
+ $res = GET $location;
+ t_cmp($res->header($header),
+ qr{^text/test-output},
+ "$header header");
+};
+
+sok {
+ my $header = 'X-Perl-Module';
+ $res = GET $location;
+ t_cmp($res->header($header),
+ $module,
+ "$header header");
+};
diff --git a/2_0_13/t/modules/cgi2.t b/2_0_13/t/modules/cgi2.t
new file mode 100644
index 0000000..491ee03
--- /dev/null
+++ b/2_0_13/t/modules/cgi2.t
@@ -0,0 +1,61 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache2::Build ();
+
+my $build = Apache2::Build->build_config;
+
+use constant HAVE_LWP => have_lwp();
+
+my $tests = 4;
+$tests += 1 if HAVE_LWP;
+
+plan tests => $tests, need
+ need_min_module_version(CGI => 3.08);
+
+my $module = 'TestModules::cgi2';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+my($res, $str);
+
+sok {
+ my $url = "$location?PARAM=2";
+ $res = GET $url;
+ $str = $res->content;
+ t_cmp($str, "ok 2", "GET $url");
+};
+
+sok {
+ my $content = 'PARAM=%33';
+ $str = POST_BODY $location, content => $content;
+ t_cmp($str, "ok 3", "POST $location\n$content");
+};
+
+if (HAVE_LWP) {
+ sok {
+ t_client_log_warn_is_expected(4)
+ if $] < 5.008 && require CGI && $CGI::VERSION < 3.06;
+ $str = UPLOAD_BODY $location, content => 4;
+ t_cmp($str, "ok 4", 'file upload');
+ };
+}
+
+sok {
+ my $header = 'Content-type';
+ $res = GET $location;
+ t_cmp($res->header($header),
+ qr{^text/test-output},
+ "$header header");
+};
+
+sok {
+ my $header = 'X-Perl-Module';
+ $res = GET $location;
+ t_cmp($res->header($header),
+ $module,
+ "$header header");
+};
diff --git a/2_0_13/t/modules/cgipost.t b/2_0_13/t/modules/cgipost.t
new file mode 100644
index 0000000..0cd94f2
--- /dev/null
+++ b/2_0_13/t/modules/cgipost.t
@@ -0,0 +1,37 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(POST_BODY_ASSERT);
+
+my $module = 'TestModules::cgipost';
+my $url = '/' . Apache::TestRequest::module2path($module);
+
+my @data = (25, 50, 75, 100, 125, 150);
+
+plan tests => scalar(@data), need_min_module_version(CGI => 3.08);
+
+foreach my $post (@data) {
+ my %param = ();
+
+ foreach my $key (1 .. $post) {
+ $param{$key} = 'data' x $key;
+ }
+
+ my $post_data = join '&', map { "$_=$param{$_}" }
+ sort { $a <=> $b } keys %param;
+ my $expected = join ':', map { $param{$_} }
+ sort { $a <=> $b } keys %param;
+
+ my $e_length = length $expected;
+
+ my $received = POST_BODY_ASSERT $url, content => $post_data;
+
+ my $r_length = length $received;
+
+ t_debug "expected $e_length bytes, received $r_length bytes\n";
+ ok ($expected eq $received);
+}
+
diff --git a/2_0_13/t/modules/cgipost2.t b/2_0_13/t/modules/cgipost2.t
new file mode 100644
index 0000000..8c062f6
--- /dev/null
+++ b/2_0_13/t/modules/cgipost2.t
@@ -0,0 +1,37 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(POST_BODY_ASSERT);
+
+my $module = 'TestModules::cgipost2';
+my $url = '/' . Apache::TestRequest::module2path($module);
+
+my @data = (25, 50, 75, 100, 125, 150);
+
+plan tests => scalar(@data), need_min_module_version(CGI => 3.08);
+
+foreach my $post (@data) {
+ my %param = ();
+
+ foreach my $key (1 .. $post) {
+ $param{$key} = 'data' x $key;
+ }
+
+ my $post_data = join '&', map { "$_=$param{$_}" }
+ sort { $a <=> $b } keys %param;
+ my $expected = join ':', map { $param{$_} }
+ sort { $a <=> $b } keys %param;
+
+ my $e_length = length $expected;
+
+ my $received = POST_BODY_ASSERT $url, content => $post_data;
+
+ my $r_length = length $received;
+
+ t_debug "expected $e_length bytes, received $r_length bytes\n";
+ ok ($expected eq $received);
+}
+
diff --git a/2_0_13/t/modules/cgiupload.t b/2_0_13/t/modules/cgiupload.t
new file mode 100644
index 0000000..b0a961f
--- /dev/null
+++ b/2_0_13/t/modules/cgiupload.t
@@ -0,0 +1,38 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use Apache2::Build ();
+
+use File::Spec::Functions qw(catfile);
+
+my $build = Apache2::Build->build_config;
+plan tests => 2, need need_lwp(), need need_min_module_version('CGI', 3.08),
+ {"MP_COMPAT_1X is disabled" => $build->{MP_COMPAT_1X}};
+
+my $location = "/TestModules__cgiupload";
+
+my $filename;
+my $pod = 'pod/perlfunc.pod';
+
+for (@INC) {
+ if (-e "$_/$pod") {
+ $filename = "$_/$pod";
+ last;
+ }
+}
+
+$filename ||= catfile Apache::Test::vars('serverroot'), "..", 'Makefile';
+
+for (1,2) {
+ t_client_log_warn_is_expected(4)
+ if $] < 5.008 && require CGI && $CGI::VERSION < 3.06;
+ my $str = UPLOAD_BODY $location, filename => $filename;
+ my $body_len = length $str;
+ my $file_len = -s $filename;
+ t_debug "body_len=$body_len, file_len=$file_len";
+ ok $body_len == $file_len;
+}
diff --git a/2_0_13/t/modules/cgiupload2.t b/2_0_13/t/modules/cgiupload2.t
new file mode 100644
index 0000000..b298419
--- /dev/null
+++ b/2_0_13/t/modules/cgiupload2.t
@@ -0,0 +1,38 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use Apache2::Build ();
+
+use File::Spec::Functions qw(catfile);
+
+my $build = Apache2::Build->build_config;
+plan tests => 2, need need_lwp(),
+ need_min_module_version(CGI => 3.08);
+
+my $location = "/TestModules__cgiupload2";
+
+my $filename;
+my $pod = 'pod/perlfunc.pod';
+
+for (@INC) {
+ if (-e "$_/$pod") {
+ $filename = "$_/$pod";
+ last;
+ }
+}
+
+$filename ||= catfile Apache::Test::vars('serverroot'), "..", 'Makefile';
+
+for (1,2) {
+ t_client_log_warn_is_expected(4)
+ if $] < 5.008 && require CGI && $CGI::VERSION < 3.06;
+ my $str = UPLOAD_BODY $location, filename => $filename;
+ my $body_len = length $str;
+ my $file_len = -s $filename;
+ t_debug "body_len=$body_len, file_len=$file_len";
+ ok $body_len == $file_len;
+}
diff --git a/2_0_13/t/modules/include.t b/2_0_13/t/modules/include.t
new file mode 100644
index 0000000..a2c54b3
--- /dev/null
+++ b/2_0_13/t/modules/include.t
@@ -0,0 +1,35 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+#test for mod_include include virtual of a mod_perl script
+my @patterns = (
+ 'mod_perl mod_include test',
+ 'Hello World',
+ 'cgi.pm',
+ 'footer',
+);
+
+plan tests => 2 + @patterns, need need_module('mod_include', 'mod_mime'),
+ need_min_module_version(CGI => 3.08);
+
+my $location = "/includes/test.shtml";
+
+
+my($res, $str);
+
+$res = GET $location;
+
+ok $res->is_success;
+
+$str = $res->content;
+
+ok $str;
+
+for my $pat (@patterns) {
+ ok t_cmp($str, qr{$pat}, "/$pat/");
+}
diff --git a/2_0_13/t/modules/include2.t b/2_0_13/t/modules/include2.t
new file mode 100644
index 0000000..80d51dd
--- /dev/null
+++ b/2_0_13/t/modules/include2.t
@@ -0,0 +1,32 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+#test for mod_include parsing of mod_perl script output
+#XXX: needs to be more robust. see t/htdocs/includes-registry/test.spl
+my @patterns = (
+ 'Perl-SSI', #MY_TEST
+ 'mod_perl', #SERVER_SOFTWARE
+);
+
+plan tests => 2 + @patterns, ['include', 'mod_mime', 'HTML::HeadParser'];
+
+my $location = "/includes-registry/test.spl";
+
+my($res, $str);
+
+$res = GET $location;
+
+ok $res->is_success;
+
+$str = $res->content;
+
+ok $str;
+
+for my $pat (@patterns) {
+ ok t_cmp($str, qr{$pat}, "/$pat/");
+}
diff --git a/2_0_13/t/modules/include_subreq.t b/2_0_13/t/modules/include_subreq.t
new file mode 100644
index 0000000..8295292
--- /dev/null
+++ b/2_0_13/t/modules/include_subreq.t
@@ -0,0 +1,19 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+my $module = 'TestModules::include_subreq';
+my $location = '/' . Apache::TestRequest::module2path($module);
+
+plan tests => 1, ['include'];
+
+my($res, $str);
+
+my $expected = "subreq is quite ok";
+my $received = GET_BODY_ASSERT "$location/one";
+ok t_cmp($received, $expected, "handler => filter => handler");
+
diff --git a/2_0_13/t/modules/proxy.t b/2_0_13/t/modules/proxy.t
new file mode 100644
index 0000000..2f4a53f
--- /dev/null
+++ b/2_0_13/t/modules/proxy.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = 'TestModules::proxy';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+
+my @modules = qw(mod_proxy proxy_http.c);
+push @modules, 'mod_access_compat' if have_min_apache_version("2.4.0");
+plan tests => 1, need need_module(@modules), need_access;
+
+my $expected = "ok";
+my $received = GET_BODY_ASSERT $url;
+ok t_cmp($received, $expected, "internally proxified request");
diff --git a/2_0_13/t/perl/hash_attack.t b/2_0_13/t/perl/hash_attack.t
new file mode 100644
index 0000000..bb91ef2
--- /dev/null
+++ b/2_0_13/t/perl/hash_attack.t
@@ -0,0 +1,16 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+plan tests => 1,
+ need { "relevant only for perl 5.8.2 and up to 5.17.6" => ($] >= 5.008002 && $] < 5.017006) };
+
+my $expected = "ok";
+my $received = GET_BODY_ASSERT "/TestPerl__hash_attack";
+ok($expected eq $received);
diff --git a/2_0_13/t/perl/ithreads.t b/2_0_13/t/perl/ithreads.t
new file mode 100644
index 0000000..53757a0
--- /dev/null
+++ b/2_0_13/t/perl/ithreads.t
@@ -0,0 +1,17 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# perl/ithreads2 is a similar test but is running from within a
+# virtual host with its own perl interpreter pool (+Parent)
+
+use Config;
+
+use Apache::Test;
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+# perl < 5.6.0 fails to compile code with 'shared' attributes, so we must skip
+# it here.
+unless ($] >= 5.008001 && $Config{useithreads}) {
+ plan tests => 1, need
+ {"perl 5.8.1 or higher w/ithreads enabled is required" => 0};
+}
+
+print GET_BODY_ASSERT "/TestPerl__ithreads";
diff --git a/2_0_13/t/perl/ithreads2.t b/2_0_13/t/perl/ithreads2.t
new file mode 100644
index 0000000..ec2718b
--- /dev/null
+++ b/2_0_13/t/perl/ithreads2.t
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# perl/ithreads is a similar test but is running from the global perl
+# interpreter pool. whereas this test is running against a
+# virtual host with its own perl interpreter pool (+Parent)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Config;
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+# perl < 5.6.0 fails to compile code with 'shared' attributes, so we must skip
+# it here.
+unless ($] >= 5.008001 && $Config{useithreads}) {
+ plan tests => 1, need
+ {"perl 5.8.1 or higher w/ithreads enabled is required" => 0};
+}
+
+my $module = 'TestPerl::ithreads';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/perl/ithreads3.t b/2_0_13/t/perl/ithreads3.t
new file mode 100644
index 0000000..ef3feb5
--- /dev/null
+++ b/2_0_13/t/perl/ithreads3.t
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest 'GET_BODY';
+
+plan tests => 6, need_apache_mpm('worker') && need_perl('ithreads');
+
+my $module = 'TestPerl::ithreads3';
+
+sub u {Apache::TestRequest::module2url($module, {path=>$_[0]})}
+sub t {
+ my $rc;
+ eval {
+ local $SIG{ALRM}=sub {die "Timeout\n"};
+ alarm 2;
+ eval {
+ $rc=GET_BODY u(shift);
+ };
+ alarm 0;
+ };
+ alarm 0;
+ return $rc;
+}
+
+t_debug("connecting to ".u(''));
+ok t_cmp t('/perl-script?1'), 2, 'perl-script 1';
+ok t_cmp t('/modperl?1'), 2, 'modperl 1';
+
+ok t_cmp t('/perl-script?2'), 5, 'perl-script 2';
+ok t_cmp t('/modperl?2'), 5, 'modperl 2';
+
+ok t_cmp t('/perl-script?3'), 3, 'perl-script 3';
+ok t_cmp t('/modperl?3'), 3, 'modperl 3';
diff --git a/2_0_13/t/preconnection/TestPreConnection/note.pm b/2_0_13/t/preconnection/TestPreConnection/note.pm
new file mode 100644
index 0000000..f485952
--- /dev/null
+++ b/2_0_13/t/preconnection/TestPreConnection/note.pm
@@ -0,0 +1,50 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPreConnection::note;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+
+use Apache::TestTrace;
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+sub handler {
+ my Apache2::Connection $c = shift;
+
+ my $ip = APACHE24 ? $c->client_ip : $c->remote_ip;
+
+ debug "ip: $ip";
+
+ $c->notes->set(preconnection => $ip);
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->print($r->connection->notes->get('preconnection') || '');
+
+ return Apache2::Const::OK
+}
+
+1;
+__END__
+<NoAutoConfig>
+ <VirtualHost TestPreConnection::note>
+ PerlPreConnectionHandler TestPreConnection::note
+
+ <Location /TestPreConnection__note>
+ SetHandler modperl
+ PerlResponseHandler TestPreConnection::note::response
+ </Location>
+ </VirtualHost>
+</NoAutoConfig>
+
+
diff --git a/2_0_13/t/preconnection/note.t b/2_0_13/t/preconnection/note.t
new file mode 100644
index 0000000..29453db
--- /dev/null
+++ b/2_0_13/t/preconnection/note.t
@@ -0,0 +1,20 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $module = 'TestPreConnection::note';
+my $url = Apache::TestRequest::module2url($module);
+my $config = Apache::Test::config();
+
+my $remote_addr = $config->{vars}->{remote_addr};
+t_debug("connecting to $url");
+plan tests => 1;
+
+ok t_cmp(
+ GET_BODY_ASSERT($url),
+ $remote_addr,
+ "connection notes");
diff --git a/2_0_13/t/protocol/TestProtocol/echo_bbs.pm b/2_0_13/t/protocol/TestProtocol/echo_bbs.pm
new file mode 100644
index 0000000..1951b0e
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/echo_bbs.pm
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::echo_bbs;
+
+# this test is similar to TestProtocol::echo_filter, but performs the
+# manipulations on the buckets inside the connection handler, rather
+# then using filter
+
+# it also demonstrates how to use a single bucket bridade to do all
+# the manipulation
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+use APR::Bucket ();
+use APR::Brigade ();
+use APR::Error ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK MODE_GETLINE);
+use APR::Const -compile => qw(SUCCESS SO_NONBLOCK);
+use APR::Status ();
+
+sub handler {
+ my $c = shift;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
+
+ while (1) {
+ debug "asking new line";
+ my $rc = $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE);
+ last if APR::Status::is_EOF($rc);
+ die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
+
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+
+ last if $b->is_eos;
+
+ debug "processing new line";
+
+ if ($b->read(my $data)) {
+ last if $data =~ /^[\r\n]+$/;
+ my $nb = APR::Bucket->new($bb->bucket_alloc, uc $data);
+ # head->...->$nb->$b ->...->tail
+ # XXX: the next 3 lines could be replaced with a
+ # wrapper function $b->replace($nb);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
+ }
+ }
+
+ $c->output_filters->fflush($bb);
+ }
+
+ $bb->destroy;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_bbs2.pm b/2_0_13/t/protocol/TestProtocol/echo_bbs2.pm
new file mode 100644
index 0000000..dacf27f
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/echo_bbs2.pm
@@ -0,0 +1,59 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::echo_bbs2;
+
+# similar to TestProtocol::echo_bbs but here re-using one bucket
+# brigade for input and output, using flatten to slurp all the data in
+# the bucket brigade, and cleanup to get rid of the old buckets
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+use APR::Bucket ();
+use APR::Brigade ();
+use APR::Error ();
+
+use Apache2::Const -compile => qw(OK MODE_GETLINE);
+use APR::Const -compile => qw(SUCCESS SO_NONBLOCK);
+use APR::Status ();
+
+sub handler {
+ my $c = shift;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc);
+ my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc);
+
+ my $last = 0;
+ while (1) {
+ my $rc = $c->input_filters->get_brigade($bb_in,
+ Apache2::Const::MODE_GETLINE);
+ last if APR::Status::is_EOF($rc);
+ die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
+
+ next unless $bb_in->flatten(my $data);
+ #warn "read: [$data]\n";
+ last if $data =~ /^[\r\n]+$/;
+
+ # transform data here
+ my $bucket = APR::Bucket->new($bb_in->bucket_alloc, uc $data);
+ $bb_out->insert_tail($bucket);
+
+ $c->output_filters->fflush($bb_out);
+
+ $bb_in->cleanup;
+ $bb_out->cleanup;
+ }
+
+ # XXX: add DESTROY and remove explicit calls
+ $bb_in->destroy;
+ $bb_out->destroy;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_block.pm b/2_0_13/t/protocol/TestProtocol/echo_block.pm
new file mode 100644
index 0000000..e13f93d
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/echo_block.pm
@@ -0,0 +1,48 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::echo_block;
+
+# this test reads from/writes to the socket doing blocking IO
+#
+# see TestProtocol::echo_timeout for how to do the same with
+# nonblocking IO but using the timeout
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+
+use TestCommon::Utils;
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => qw(SO_NONBLOCK);
+
+use constant BUFF_LEN => 1024;
+
+sub handler {
+ my Apache2::Connection $c = shift;
+ my APR::Socket $socket = $c->client_socket;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ my $nonblocking = $socket->opt_get(APR::Const::SO_NONBLOCK);
+ if ($nonblocking) {
+ $socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ # test that we really *are* in the blocking mode
+ !$socket->opt_get(APR::Const::SO_NONBLOCK)
+ or die "failed to set blocking mode";
+ }
+
+ while ($socket->recv(my $buffer, BUFF_LEN)) {
+
+ die "recv() has returned untainted data:"
+ unless TestCommon::Utils::is_tainted($buffer);
+
+ $socket->send($buffer);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_filter.pm b/2_0_13/t/protocol/TestProtocol/echo_filter.pm
new file mode 100644
index 0000000..91d19f6
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/echo_filter.pm
@@ -0,0 +1,64 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::echo_filter;
+
+# see also TestFilter::both_str_con_add
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+use APR::Bucket ();
+use APR::Brigade ();
+use APR::Error ();
+
+use base qw(Apache2::Filter);
+
+use APR::Const -compile => qw(SUCCESS SO_NONBLOCK);
+use APR::Status ();
+use Apache2::Const -compile => qw(OK MODE_GETLINE);
+
+use constant BUFF_LEN => 1024;
+
+sub uc_filter : FilterConnectionHandler {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, BUFF_LEN)) {
+ $filter->print(uc $buffer);
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $c = shift;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
+
+ while (1) {
+ my $rc = $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE);
+ last if APR::Status::is_EOF($rc);
+ die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
+
+ # fflush is the equivalent of the following 3 lines of code:
+ #
+ # my $b = APR::Bucket::flush_create($c->bucket_alloc);
+ # $bb->insert_tail($b);
+ # $c->output_filters->pass_brigade($bb);
+ $c->output_filters->fflush($bb);
+ }
+
+ $bb->destroy;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+PerlModule TestProtocol::echo_filter
+PerlOutputFilterHandler TestProtocol::echo_filter::uc_filter
+
diff --git a/2_0_13/t/protocol/TestProtocol/echo_nonblock.pm b/2_0_13/t/protocol/TestProtocol/echo_nonblock.pm
new file mode 100644
index 0000000..d99d576
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/echo_nonblock.pm
@@ -0,0 +1,80 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::echo_nonblock;
+
+# this test reads from/writes to the socket doing nonblocking IO
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+use APR::Error ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => qw(SO_NONBLOCK SUCCESS POLLIN);
+use APR::Status ();
+
+use constant BUFF_LEN => 1024;
+
+sub handler {
+ my $c = shift;
+ my $socket = $c->client_socket;
+
+ $socket->opt_set(APR::Const::SO_NONBLOCK, 1);
+
+ my $counter = 0;
+ my $timeout = 0;
+ while (1) {
+
+ debug "counter: $counter";
+ if ($counter == 1) {
+ # this will certainly cause timeout
+ $timeout = 0;
+ } else {
+ # Wait up to ten seconds for data to arrive.
+ $timeout = 10_000_000;
+ }
+ $counter++;
+
+ my $rc = $socket->poll($c->pool, $timeout, APR::Const::POLLIN);
+ if ($rc == APR::Const::SUCCESS) {
+ my $buf;
+ my $len = eval { $socket->recv($buf, BUFF_LEN) };
+ if ($@) {
+ # rethrow
+ die $@ unless ref $@ eq 'APR::Error'
+ && (APR::Status::is_ECONNABORTED($@) ||
+ APR::Status::is_ECONNRESET($@));
+ # ECONNABORTED == 103
+ # ECONNRESET == 104
+ # ECONNABORTED is not an application error
+ # XXX: we don't really test that we always get this
+ # condition, since it depends on the timing of the
+ # client closing the socket. may be it'd be possible
+ # to make sure that APR::Const::ECONNABORTED was received
+ # when $counter == 2 if we have slept enough, but how
+ # much is enough is unknown
+ debug "caught '104: Connection reset by peer' error";
+ last;
+ }
+
+ last unless $len;
+
+ debug "sending: $buf";
+ $socket->send($buf);
+ }
+ elsif (APR::Status::is_TIMEUP($rc)) {
+ debug "timeout";
+ $socket->send("TIMEUP\n");
+ }
+ else {
+ die "poll error: $rc: " . APR::Error::strerror($rc);
+ }
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_timeout.pm b/2_0_13/t/protocol/TestProtocol/echo_timeout.pm
new file mode 100644
index 0000000..50c81fa
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/echo_timeout.pm
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::echo_timeout;
+
+# this test reads from/writes to the socket doing nonblocking IO but
+# using the timeout
+#
+# see TestProtocol::echo_block for how to do the same with blocking IO
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => qw(SO_NONBLOCK);
+use APR::Status ();
+
+use constant BUFF_LEN => 1024;
+
+sub handler {
+ my Apache2::Connection $c = shift;
+ my APR::Socket $socket = $c->client_socket;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ # set timeout (20 sec) so later we can do error checking on
+ # read/write timeouts
+ $socket->timeout_set(20_000_000);
+
+ while (1) {
+ my $buff;
+ my $rlen = eval { $socket->recv($buff, BUFF_LEN) };
+ if ($@) {
+ die "timed out, giving up: $@" if APR::Status::is_TIMEUP($@);
+ die $@;
+ }
+
+ last unless $rlen; # EOF
+
+ my $wlen = eval { $socket->send($buff) };
+ if ($@) {
+ die "timed out, giving up: $@" if APR::Status::is_TIMEUP($@);
+ die $@;
+ }
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/protocol/TestProtocol/eliza.pm b/2_0_13/t/protocol/TestProtocol/eliza.pm
new file mode 100644
index 0000000..3e1bdac
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/eliza.pm
@@ -0,0 +1,47 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::eliza;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use APR::Socket ();
+
+require Chatbot::Eliza;
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => 'SO_NONBLOCK';
+
+use constant BUFF_LEN => 1024;
+
+my $mybot = new Chatbot::Eliza;
+
+sub handler {
+ my Apache2::Connection $c = shift;
+ my APR::Socket $socket = $c->client_socket;
+
+ # starting from Apache 2.0.49 several platforms require you to set
+ # the socket to a blocking IO mode
+ my $nonblocking = $socket->opt_get(APR::Const::SO_NONBLOCK);
+ if ($nonblocking) {
+ $socket->opt_set(APR::Const::SO_NONBLOCK, 0);
+
+ # test that we really *are* in the blocking mode
+ !$socket->opt_get(APR::Const::SO_NONBLOCK)
+ or die "failed to set blocking mode";
+ }
+
+ my $last = 0;
+ while ($socket->recv(my $buff, BUFF_LEN)) {
+ # \r is sent instead of \n if the client is talking over telnet
+ $buff =~ s/[\r\n]*$//;
+ $last++ if $buff eq "Good bye, Eliza";
+ $buff = $mybot->transform( $buff ) . "\n";
+ $socket->send($buff);
+ last if $last;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/protocol/TestProtocol/pseudo_http.pm b/2_0_13/t/protocol/TestProtocol/pseudo_http.pm
new file mode 100644
index 0000000..3aede65
--- /dev/null
+++ b/2_0_13/t/protocol/TestProtocol/pseudo_http.pm
@@ -0,0 +1,196 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestProtocol::pseudo_http;
+
+# this is a more advanced protocol implementation. While using a
+# simplistic socket communication, the protocol uses an almost
+# complete HTTP AAA (access and authentication, but not authorization,
+# which can be easily added) provided by mod_auth (but can be
+# implemented in perl too)
+#
+# see the protocols.pod document for the explanations of the code
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Connection ();
+use Apache2::RequestUtil ();
+use Apache2::HookRun ();
+use Apache2::Access ();
+use APR::Socket ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK DONE DECLINED);
+use APR::Const -compile => qw(SO_NONBLOCK);
+
+my @cmds = qw(date quit);
+my %commands = map { $_, \&{$_} } @cmds;
+
+sub handler {
+ my $c = shift;
+ my $socket = $c->client_socket;
+
+ if ($socket->opt_get(APR::Const::SO_NONBLOCK)) {
+ $socket->opt_set(APR::Const::SO_NONBLOCK => 0);
+ }
+
+ if ((my $rc = greet($c)) != Apache2::Const::OK) {
+ $socket->send("Say HELO first\n");
+ return $rc;
+ }
+
+ if ((my $rc = login($c)) != Apache2::Const::OK) {
+ $socket->send("Access Denied\n");
+ return $rc;
+ }
+
+ $socket->send("Welcome to " . __PACKAGE__ .
+ "\nAvailable commands: @cmds\n");
+
+ while (1) {
+ my $cmd;
+ next unless $cmd = getline($socket);
+
+ if (my $sub = $commands{$cmd}) {
+ last unless $sub->($socket) == Apache2::Const::OK;
+ }
+ else {
+ $socket->send("Commands: @cmds\n");
+ }
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub greet {
+ my $c = shift;
+ my $socket = $c->client_socket;
+
+ $socket->send("HELO\n");
+ my $reply = getline($socket) || '';
+
+ return $reply eq 'HELO' ? Apache2::Const::OK : Apache2::Const::DECLINED;
+}
+
+sub login {
+ my $c = shift;
+
+ my $r = Apache2::RequestRec->new($c);
+
+ # test whether we can invoke modperl HTTP handlers on the fake $r
+ $r->push_handlers(PerlAccessHandler => \&my_access);
+
+ $r->location_merge(__PACKAGE__);
+
+ for my $method (qw(run_access_checker run_check_user_id
+ run_auth_checker)) {
+
+ my $rc = $r->$method();
+
+ if ($rc != Apache2::Const::OK and $rc != Apache2::Const::DECLINED) {
+ return $rc;
+ }
+
+ last unless $r->some_auth_required;
+
+ unless ($r->user) {
+ my $socket = $c->client_socket;
+
+ my $username = prompt($socket, "Login");
+ my $password = prompt($socket, "Password");
+
+ $r->set_basic_credentials($username, $password);
+ }
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub my_access {
+ # just test that we can invoke a mod_perl HTTP handler
+ debug "running my_access";
+ return Apache2::Const::OK;
+}
+
+sub getline {
+ my $socket = shift;
+
+ my $line;
+ $socket->recv($line, 1024);
+ return unless $line;
+ $line =~ s/[\r\n]*$//;
+
+ return $line;
+}
+
+sub prompt {
+ my ($socket, $msg) = @_;
+
+ $socket->send("$msg:\n");
+ getline($socket);
+}
+
+sub date {
+ my $socket = shift;
+
+ $socket->send("The time is: " . scalar(localtime) . "\n");
+
+ return Apache2::Const::OK;
+}
+
+sub quit {
+ my $socket = shift;
+
+ $socket->send("Goodbye\n");
+
+ return Apache2::Const::DONE
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestProtocol::pseudo_http>
+
+ PerlProcessConnectionHandler TestProtocol::pseudo_http
+
+ <Location TestProtocol::pseudo_http>
+
+ <IfModule mod_version.c>
+ <IfVersion < 2.3.0>
+ <IfModule @ACCESS_MODULE@>
+ Order Deny,Allow
+ Allow from @servername@
+ </IfModule>
+ </IfVersion>
+ <IfVersion > 2.4.1>
+ <IfModule mod_access_compat.c>
+ Order Deny,Allow
+ Allow from @servername@
+ </IfModule>
+ </IfVersion>
+ </IfModule>
+
+ <IfModule @AUTH_MODULE@>
+ # htpasswd -mbc basic-auth stas foobar
+ # using md5 password so it'll work on win32 too
+ AuthUserFile @ServerRoot@/htdocs/protocols/basic-auth
+ </IfModule>
+
+ AuthName TestProtocol::pseudo_http
+ AuthType Basic
+ Require user stas
+ <IfModule mod_version.c>
+ <IfVersion < 2.3.0>
+ Satisfy any
+ </IfVersion>
+ <IfVersion > 2.4.1>
+ <IfModule mod_access_compat.c>
+ Satisfy any
+ </IfModule>
+ </IfVersion>
+ </IfModule>
+
+ </Location>
+
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/protocol/echo_bbs.t b/2_0_13/t/protocol/echo_bbs.t
new file mode 100644
index 0000000..a5080cf
--- /dev/null
+++ b/2_0_13/t/protocol/echo_bbs.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = qw(hello wonderful world);
+
+plan tests => 1 + @test_strings;
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_bbs');
+
+ok $socket;
+
+for (@test_strings) {
+ print $socket "$_\n";
+ chomp(my $reply = <$socket>||'');
+ ok t_cmp($reply, uc($_));
+}
diff --git a/2_0_13/t/protocol/echo_bbs2.t b/2_0_13/t/protocol/echo_bbs2.t
new file mode 100644
index 0000000..1dd3329
--- /dev/null
+++ b/2_0_13/t/protocol/echo_bbs2.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = qw(hello world);
+
+plan tests => 1 + @test_strings;
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_bbs2');
+
+ok $socket;
+
+for (@test_strings) {
+ print $socket "$_\n";
+ chomp(my $reply = <$socket>||'');
+ ok t_cmp($reply, uc($_));
+}
diff --git a/2_0_13/t/protocol/echo_block.t b/2_0_13/t/protocol/echo_block.t
new file mode 100644
index 0000000..30715b5
--- /dev/null
+++ b/2_0_13/t/protocol/echo_block.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = qw(hello world);
+
+# blocking socket bug fixed in 2.0.52
+my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52');
+
+plan tests => 1 + @test_strings, $ok;
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_block');
+
+ok $socket;
+
+for (@test_strings) {
+ print $socket "$_\n";
+ chomp(my $reply = <$socket>||'');
+ ok t_cmp($reply, $_);
+}
diff --git a/2_0_13/t/protocol/echo_filter.t b/2_0_13/t/protocol/echo_filter.t
new file mode 100644
index 0000000..b311af1
--- /dev/null
+++ b/2_0_13/t/protocol/echo_filter.t
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = qw(hello world);
+
+# blocking socket bug fixed in 2.0.52
+my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52');
+
+plan tests => 1 + @test_strings, $ok;
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_filter');
+
+ok $socket;
+
+for (@test_strings) {
+ print $socket "$_\n";
+ chomp(my $reply = <$socket>||'');
+ ok t_cmp($reply, uc($_));
+}
diff --git a/2_0_13/t/protocol/echo_nonblock.t b/2_0_13/t/protocol/echo_nonblock.t
new file mode 100644
index 0000000..0de4da8
--- /dev/null
+++ b/2_0_13/t/protocol/echo_nonblock.t
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+plan tests => 3;
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_nonblock');
+
+ok $socket;
+
+my $received;
+my $expected;
+
+$expected = "nonblocking";
+print $socket "$expected\n";
+chomp($received = <$socket> || '');
+ok t_cmp $received, $expected, "no timeout";
+
+# now get a timed out request
+$expected = "TIMEUP";
+sleep 1; # try to ensure a CPU context switch for the server
+print $socket "should timeout\n";
+chomp($received = <$socket> || '');
+ok t_cmp $received, $expected, "timed out";
+
diff --git a/2_0_13/t/protocol/echo_timeout.t b/2_0_13/t/protocol/echo_timeout.t
new file mode 100644
index 0000000..261b448
--- /dev/null
+++ b/2_0_13/t/protocol/echo_timeout.t
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = qw(good bye cruel world);
+
+plan tests => 1 + @test_strings;
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_timeout');
+
+ok $socket;
+
+for (@test_strings) {
+ print $socket "$_\n";
+ chomp(my $reply = <$socket>||'');
+ ok t_cmp($reply, $_);
+}
diff --git a/2_0_13/t/protocol/eliza.t b/2_0_13/t/protocol/eliza.t
new file mode 100644
index 0000000..0df216f
--- /dev/null
+++ b/2_0_13/t/protocol/eliza.t
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my @test_strings = ('Hello Eliza',
+ 'How are you?',
+ 'Why do I have core dumped?',
+ 'I feel like writing some tests today, what about you?',
+ 'Good bye, Eliza');
+
+plan tests => 2 + @test_strings, need_module 'Chatbot::Eliza';
+
+my $socket = Apache::TestRequest::vhost_socket('TestProtocol::eliza');
+
+ok $socket;
+
+for (@test_strings) {
+ print $socket "$_\n";
+ chomp(my $reply = <$socket> || '');
+ t_debug "send: $_";
+ t_debug "recv: $reply";
+ ok $reply;
+}
+
+# at this point 'Good bye, Eliza' should abort the connection.
+my $string = 'Eliza should not hear this';
+print $socket "$string\n";
+chomp(my $reply = <$socket> || '');
+t_debug "Eliza shouldn't respond anymore";
+ok !$reply;
diff --git a/2_0_13/t/protocol/pseudo_http.t b/2_0_13/t/protocol/pseudo_http.t
new file mode 100644
index 0000000..586c6ac
--- /dev/null
+++ b/2_0_13/t/protocol/pseudo_http.t
@@ -0,0 +1,148 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest ();
+
+my $module = 'TestProtocol::pseudo_http';
+
+{
+ # debug
+ Apache::TestRequest::module($module);
+ my $hostport = Apache::TestRequest::hostport(Apache::Test::config());
+ t_debug("connecting to $hostport");
+}
+
+my $login = "stas";
+my $passgood = "foobar";
+my $passbad = "foObaR";
+
+# blocking socket bug fixed in 2.0.52
+my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52');
+
+my @modules = ();
+push @modules, 'mod_access_compat.c' if have_min_apache_version("2.4.0");
+plan tests => 13, need need_auth, need_access, @modules, $ok;
+
+{
+ # supply correct credential when prompted for such and ask the
+ # server get the secret datetime information
+ my $socket = Apache::TestRequest::vhost_socket($module);
+ ok $socket;
+
+ ####################################################################
+ # ACTION SEND RECEIVE
+ #
+ # greeting HELO
+ # HELO
+ # Login:
+ #
+ # login $login
+ # Password
+ #
+ # good pass $passgood
+ # banner Welcome to TestProtocol::pseudo_http
+ # Available commands: date quit
+ # date date
+ # The time is: Sat Jul 8 23:51:47 2006
+ #
+ # eot quit
+ # Goodbye
+
+ {
+ my $response = "";
+ $response = Send($socket, 'HELO');
+ ok t_cmp($response, 'HELO', 'greeting 1');
+ $response = getline($socket);
+ ok t_cmp($response, 'Login:', 'greeeting 2')
+ }
+
+ {
+ my $response = Send($socket, $login);
+ ok t_cmp($response, 'Password:', 'login');
+ }
+
+ {
+ my $response = "";
+ $response = Send($socket, $passgood);
+ ok t_cmp($response, 'Welcome to TestProtocol::pseudo_http', 'good pass');
+ $response = getline($socket);
+ ok t_cmp($response, 'Available commands: date quit', 'banner');
+ }
+
+ {
+ my $response = Send($socket, 'date');
+ ok t_cmp($response, qr/The time is:/, 'date');
+ }
+
+ {
+ my $response = Send($socket, 'quit');
+ ok t_cmp($response, 'Goodbye', 'eot');
+ }
+}
+
+{
+ # supply correct credential when prompted for such and ask the
+ # server get the secret datetime information
+ my $socket = Apache::TestRequest::vhost_socket($module);
+ ok $socket;
+
+ ####################################################################
+ # ACTION SEND RECEIVE
+ #
+ # greeting HELO
+ # HELO
+ # Login:
+ #
+ # login $login
+ # Password
+ #
+ # bad pass $passbad
+ # Access Denied
+ #
+ # eot quit
+ # Goodbye
+
+ {
+ my $response = "";
+ $response = Send($socket, 'HELO');
+ ok t_cmp($response, 'HELO', 'greeting 1');
+ $response = getline($socket);
+ ok t_cmp($response, 'Login:', 'greeeting 2')
+ }
+
+ {
+ my $response = Send($socket, $login);
+ ok t_cmp($response, 'Password:', 'login');
+ }
+
+ {
+ my $response = "";
+ $response = Send($socket, $passbad);
+ ok t_cmp($response, 'Access Denied', 'eot');
+ }
+}
+
+## send() is reserved
+sub Send {
+ my ($socket, $str) = @_;
+
+ t_debug("send: $str");
+ print $socket $str;
+
+ chomp(my $recv = <$socket> || '');
+ t_debug("recv: $recv");
+
+ return $recv;
+}
+
+sub getline {
+ my ($socket) = @_;
+
+ chomp(my $recv = <$socket> || '');
+ t_debug("getline: $recv");
+
+ return $recv;
+}
diff --git a/2_0_13/t/response/TestAPI/access.pm b/2_0_13/t/response/TestAPI/access.pm
new file mode 100644
index 0000000..82b1a03
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/access.pm
@@ -0,0 +1,65 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::access;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Access ();
+
+use Apache2::Const -compile => qw(OK :options :override :satisfy);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 11;
+
+ $r->allow_methods(1, qw(GET POST));
+
+ ok 1;
+
+ ok $r->allow_options & Apache2::Const::OPT_INDEXES;
+
+ ok !($r->allow_options & Apache2::Const::OPT_EXECCGI);
+
+ ok !($r->allow_overrides & Apache2::Const::OR_LIMIT);
+
+ ok t_cmp $r->satisfies, Apache2::Const::SATISFY_NOSPEC, "satisfies";
+
+ ok t_cmp $r->auth_name, 'modperl', "auth_name";
+
+ $r->auth_name('modperl_test');
+ ok t_cmp $r->auth_name, 'modperl_test', "auth_name";
+ $r->auth_name('modperl');
+
+ ok t_cmp $r->auth_type, 'none', "auth_type";
+
+ $r->auth_type('Basic');
+ ok t_cmp $r->auth_type, 'Basic', "auth_type";
+ $r->auth_type('none');
+
+ ok !$r->some_auth_required;
+
+ # XXX: this test requires a running identd, which we have no way
+ # to figure out whether it's running, or how to start one. so for
+ # now just check that the method is call-able.
+ my $remote_logname = $r->get_remote_logname() || '';
+ t_debug "get_remote_logname: $remote_logname";
+ ok 1;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+Options None
+Options Indexes FollowSymLinks
+AuthName modperl
+AuthType none
+
+# this directive was moved from core in Apache 2.1
+# since we're not testing that identd is running
+# anyway we probably don't need to include it at all
+#IdentityCheck On
diff --git a/2_0_13/t/response/TestAPI/access2.pm b/2_0_13/t/response/TestAPI/access2.pm
new file mode 100644
index 0000000..5677408
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/access2.pm
@@ -0,0 +1,125 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::access2;
+
+# testing $r->requires
+# in the POST test it returns:
+#
+# [
+# {
+# 'method_mask' => -1,
+# 'requirement' => 'user goo bar'
+# },
+# {
+# 'method_mask' => -1,
+# 'requirement' => 'group bar tar'
+# }
+# {
+# 'method_mask' => 4,
+# 'requirement' => 'valid-user'
+# }
+# ];
+#
+# otherwise it returns the same, sans the 'valid-user' entry
+#
+# also test:
+# - $r->some_auth_required when it's required
+# - $r->satisfies when Satisfy is set
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Access ();
+use Apache2::RequestRec ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR
+ M_POST :satisfy);
+
+my $users = "goo bar";
+my $groups = "bar tar";
+my %users = (
+ goo => "goopass",
+ bar => "barpass",
+);
+
+sub handler {
+ my $r = shift;
+ die '$r->some_auth_required failed' unless $r->some_auth_required;
+
+ my $satisfies = $r->satisfies;
+ die "wanted satisfies=" . Apache2::Const::SATISFY_ALL . ", got $satisfies"
+ unless $r->satisfies() == Apache2::Const::SATISFY_ALL;
+
+ my ($rc, $sent_pw) = $r->get_basic_auth_pw;
+ return $rc if $rc != Apache2::Const::OK;
+
+ # extract just the requirement entries
+ my %require =
+ map { my ($k, $v) = split /\s+/, $_->{requirement}, 2; ($k, $v||'') }
+ @{ $r->requires };
+ debug \%require;
+
+ # silly (we don't check user/pass here), just checking when
+ # the Limit options are getting through
+ if ($r->method_number == Apache2::Const::M_POST) {
+ if (exists $require{"valid-user"}) {
+ return Apache2::Const::OK;
+ }
+ else {
+ return Apache2::Const::SERVER_ERROR;
+ }
+ }
+ else {
+ # non-POST requests shouldn't see the Limit enclosed entry
+ return Apache2::Const::SERVER_ERROR if exists $require{"valid-user"};
+ }
+
+ return Apache2::Const::SERVER_ERROR unless $require{user} eq $users;
+ return Apache2::Const::SERVER_ERROR unless $require{group} eq $groups;
+
+ my $user = $r->user;
+ my $pass = $users{$user} || '';
+ unless (defined $pass and $sent_pw eq $pass) {
+ $r->note_basic_auth_failure;
+ return Apache2::Const::HTTP_UNAUTHORIZED;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
+<NoAutoConfig>
+<IfModule mod_version.c>
+<IfVersion < 2.3.0>
+<Location /TestAPI__access2>
+ PerlAuthenHandler TestAPI::access2
+ PerlResponseHandler Apache::TestHandler::ok1
+ SetHandler modperl
+
+ <IfModule @ACCESS_MODULE@>
+ # needed to test $r->satisfies
+ Allow from All
+ </IfModule>
+ AuthType Basic
+ AuthName "Access"
+ Require user goo bar
+ Require group bar tar
+ <Limit POST>
+ Require valid-user
+ </Limit>
+ Satisfy All
+ <IfModule @AUTH_MODULE@>
+ # htpasswd -mbc auth-users goo foo
+ # htpasswd -mb auth-users bar mar
+ # using md5 password so it'll work on win32 too
+ AuthUserFile @DocumentRoot@/api/auth-users
+ # group: user1 user2 ...
+ AuthGroupFile @DocumentRoot@/api/auth-groups
+ </IfModule>
+</Location>
+</IfVersion>
+</IfModule>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/access2_24.pm b/2_0_13/t/response/TestAPI/access2_24.pm
new file mode 100644
index 0000000..b9ab26f
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/access2_24.pm
@@ -0,0 +1,132 @@
+package TestAPI::access2_24;
+
+# testing $r->requires
+# in the POST test it returns:
+#
+# [
+# {
+# 'method_mask' => -1,
+# 'requirement' => 'user goo bar'
+# },
+# {
+# 'method_mask' => -1,
+# 'requirement' => 'group bar tar'
+# }
+# {
+# 'method_mask' => 4,
+# 'requirement' => 'valid-user'
+# }
+# ];
+#
+# otherwise it returns the same, sans the 'valid-user' entry
+#
+# also test:
+# - $r->some_auth_required when it's required
+# - $r->satisfies when Satisfy is set
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Access ();
+use Apache2::RequestRec ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR
+ AUTHZ_GRANTED AUTHZ_DENIED M_POST :satisfy
+ AUTHZ_DENIED_NO_USER);
+
+my $users = "goo bar";
+my $groups = "xar tar";
+my %users = (
+ goo => "goopass",
+ bar => "barpass",
+);
+
+sub authz_handler {
+ my $self = shift;
+ my $r = shift;
+ my $requires = shift;
+
+ if (!$r->user) {
+ return Apache2::Const::AUTHZ_DENIED_NO_USER;
+ }
+
+ return Apache2::Const::SERVER_ERROR unless
+ $requires eq $users or $requires eq $groups;
+
+ my @require_args = split(/\s+/, $requires);
+ if (grep {$_ eq $r->user} @require_args) {
+ return Apache2::Const::AUTHZ_GRANTED;
+ }
+
+ return Apache2::Const::AUTHZ_DENIED;
+}
+
+sub authn_handler {
+ my $self = shift;
+ my $r = shift;
+
+ die '$r->some_auth_required failed' unless $r->some_auth_required;
+
+ my $satisfies = $r->satisfies;
+ die "wanted satisfies=" . Apache2::Const::SATISFY_ALL . ", got $satisfies"
+ unless $r->satisfies() == Apache2::Const::SATISFY_ALL;
+
+ my ($rc, $sent_pw) = $r->get_basic_auth_pw;
+ return $rc if $rc != Apache2::Const::OK;
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ return Apache2::Const::OK;
+ }
+
+ my $user = $r->user;
+ my $pass = $users{$user} || '';
+ unless (defined $pass and $sent_pw eq $pass) {
+ $r->note_basic_auth_failure;
+ return Apache2::Const::HTTP_UNAUTHORIZED;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
+<NoAutoConfig>
+<IfModule mod_version.c>
+<IfVersion > 2.4.1>
+
+PerlAddAuthzProvider my-user TestAPI::access2_24->authz_handler
+PerlAddAuthzProvider my-group TestAPI::access2_24->authz_handler
+<Location /TestAPI__access2>
+ PerlAuthenHandler TestAPI::access2_24->authn_handler
+ PerlResponseHandler Apache::TestHandler::ok1
+ SetHandler modperl
+
+ <IfModule mod_access_compat.c>
+ # needed to test $r->satisfies
+ Allow from All
+ </IfModule>
+ AuthType Basic
+ AuthName "Access"
+ Require my-user goo bar
+ Require my-group xar tar
+ <Limit POST>
+ Require valid-user
+ </Limit>
+ <IfModule mod_access_compat.c>
+ Satisfy All
+ </IfModule>
+ <IfModule @AUTH_MODULE@>
+ # htpasswd -mbc auth-users goo foo
+ # htpasswd -mb auth-users bar mar
+ # using md5 password so it'll work on win32 too
+ AuthUserFile @DocumentRoot@/api/auth-users
+ # group: user1 user2 ...
+ AuthGroupFile @DocumentRoot@/api/auth-groups
+ </IfModule>
+</Location>
+</IfVersion>
+</IfModule>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/add_config.pm b/2_0_13/t/response/TestAPI/add_config.pm
new file mode 100644
index 0000000..661608c
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/add_config.pm
@@ -0,0 +1,149 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::add_config;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Access ();
+use Apache2::CmdParms ();
+use Apache2::RequestUtil ();
+use Apache2::Directive ();
+use Apache2::ServerUtil ();
+use base qw(Apache2::Module);
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(
+ OK
+ DECLINED
+ :options
+);
+
+use constant KEY => "TestAddConfig";
+use constant APACHE22 => have_min_apache_version('2.2.0');
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+my @directives = (
+ {
+ name => KEY,
+ cmd_data => 'cmd_data',
+ errmsg => 'errmsg',
+ },
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub TestAddConfig {
+ my ($self, $parms, $args) = @_;
+ my $srv_cfg = $self->get_config($parms->server);
+ $srv_cfg->{override_opts} = $parms->override_opts();
+}
+
+sub map2storage {
+ my $r = shift;
+
+ my $o = APACHE22 ? '=All,SymLinksIfOwnerMatch' : '';
+
+ eval {
+ $r->add_config(['AllowOverride All Options'.$o]);
+ };
+ $r->pnotes(add_config1 => "$@");
+
+ eval {
+ $r->add_config(['Options ExecCGI'], -1, '/', 0);
+ };
+ $r->pnotes(add_config2 => "$@");
+
+ # We can set AllowOverride only from .htacces in 2.4.0+
+ if (!APACHE24) {
+ eval {
+ $r->add_config(['AllowOverride Options=FollowSymLinks'], -1);
+ };
+ $r->pnotes(followsymlinks => "$@");
+ }
+
+ eval {
+ my $path="/a/path/to/somewhere";
+ $r->add_config(['PerlResponseHandler '.__PACKAGE__], -1, $path);
+ # now overwrite the path in place to see if the location pointer
+ # is really copied: see modperl_config_dir_create
+ $path=~tr[a-z][n-za-m];
+ };
+
+ return Apache2::Const::DECLINED;
+}
+
+sub fixup {
+ my ($r) = @_;
+
+ eval {
+ $r->add_config(['Options ExecCGI'], -1, '/',
+ Apache2::Const::OPT_EXECCGI);
+ };
+ $r->pnotes(add_config3 => "$@");
+
+ eval {
+ $r->server->add_config(['ServerAdmin foo@bar.com']);
+ };
+ $r->pnotes(add_config4 => "$@");
+
+ return Apache2::Const::DECLINED;
+}
+
+sub handler : method {
+ my ($self, $r) = @_;
+ my $cf = $self->get_config($r->server);
+
+ plan $r, tests => 9;
+
+ ok t_cmp $r->pnotes('add_config1'), qr/.+\n/;
+ ok t_cmp $r->pnotes('add_config2'), (APACHE22 ? qr/.+\n/ : '');
+ ok t_cmp $r->pnotes('add_config3'), '';
+ ok t_cmp $r->pnotes('add_config4'), qr/after server startup/;
+ if (!APACHE24) {
+ ok t_cmp $r->pnotes('followsymlinks'), (APACHE22 ? '': qr/.*\n/);
+ }
+ else {
+ ok 1;
+ }
+
+ my $expect = Apache2::Const::OPT_ALL |
+ Apache2::Const::OPT_UNSET |
+ (defined &Apache2::Const::OPT_INCNOEXEC
+ ? Apache2::Const::OPT_INCNOEXEC() : 0) |
+ Apache2::Const::OPT_MULTI |
+ Apache2::Const::OPT_SYM_OWNER;
+
+ ok t_cmp $cf->{override_opts}, $expect;
+ ok t_cmp $r->allow_options, Apache2::Const::OPT_EXECCGI;
+
+ my $opts = APACHE22 ? Apache2::Const::OPT_SYM_LINKS : $expect;
+ if (!APACHE24) {
+ ok t_cmp $r->allow_override_opts, $opts;
+ }
+ else {
+ ok 1;
+ }
+
+ ok t_cmp $r->location, '/a/path/to/somewhere';
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+<NoAutoConfig>
+ <VirtualHost TestAPI::add_config>
+ PerlLoadModule TestAPI::add_config
+ AccessFileName htaccess
+ SetHandler modperl
+ <Directory @DocumentRoot@>
+ AllowOverride All
+ </Directory>
+ PerlMapToStorageHandler TestAPI::add_config::map2storage
+ PerlFixupHandler TestAPI::add_config::fixup
+ </VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/aplog.pm b/2_0_13/t/response/TestAPI/aplog.pm
new file mode 100644
index 0000000..9cbef98
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/aplog.pm
@@ -0,0 +1,282 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::aplog;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::ServerRec qw(warn); # override warn locally
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::Log ();
+use Apache2::MPM ();
+
+use File::Spec::Functions qw(catfile);
+
+use Apache::Test;
+use Apache::TestUtil;
+use TestCommon::LogDiff;
+
+use Apache2::Const -compile => qw(OK :log);
+use APR::Const -compile => qw(:error SUCCESS);
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+my @LogLevels = qw(emerg alert crit error warn notice info debug);
+my $package = __PACKAGE__;
+
+my $path = catfile Apache::Test::vars('serverroot'),
+ qw(logs error_log);
+
+sub handler {
+ my $r = shift;
+ my $s = $r->server;
+
+ plan $r, tests => (@LogLevels * 2) + 20;
+
+ my $logdiff = TestCommon::LogDiff->new($path);
+
+ my $rlog = $r->log;
+
+ ok $rlog->isa('Apache2::Log::Request');
+
+ my $slog = $s->log;
+
+ ok $slog->isa('Apache2::Log::Server');
+
+ t_server_log_warn_is_expected();
+ $rlog->info($package, " test in progress");
+ ok t_cmp $logdiff->diff,
+ qr/... TestAPI::aplog test in progress/,
+ '$r->log->info';
+
+ my ($file, $line) = Apache2::Log::LOG_MARK;
+ ok $file eq __FILE__;
+ ok $line == __LINE__ - 2;
+
+ for my $method (@LogLevels) {
+ # wrap in sub {}, else Test.pm tries to run the return value
+ # of ->can
+ ok sub { $rlog->can($method) };
+ ok sub { $slog->can($method) };
+ }
+
+ # log_serror
+ {
+ my $orig_log_level = 0;
+ if (APACHE24) {
+ $orig_log_level = $s->loglevel;
+ $s->loglevel(Apache2::Const::LOG_DEBUG);
+ }
+ t_server_log_warn_is_expected();
+ $s->log_serror(Apache2::Log::LOG_MARK,
+ Apache2::Const::LOG_INFO|Apache2::Const::LOG_STARTUP,
+ APR::Const::SUCCESS, "This log message comes with no header");
+ ok t_cmp $logdiff->diff,
+ qr/^This log message comes with no header$/m,
+ '$s->log_serror(LOG_MARK, LOG_INFO|LOG_STARTUP...)';
+
+ t_server_log_warn_is_expected();
+ $s->log_serror(__FILE__, __LINE__, Apache2::Const::LOG_DEBUG,
+ APR::Const::SUCCESS, "log_serror test 1");
+ ok t_cmp $logdiff->diff,
+ qr/: log_serror test 1$/m,
+ '$s->log_serror(__FILE__, __LINE__, LOG_DEBUG...)';
+
+ # the APR_EGENERAL error string changed for APR 1.0
+ my $egeneral = have_min_apache_version('2.1.0')
+ ? qr/Internal error(?: \(specific information not available\))?/
+ : "Error string not specified yet";
+
+ t_server_log_warn_is_expected();
+ $s->log_serror(Apache2::Log::LOG_MARK, Apache2::Const::LOG_DEBUG,
+ APR::Const::EGENERAL, "log_serror test 2");
+ ok t_cmp $logdiff->diff,
+ qr/$egeneral: log_serror test 2/,
+ '$s->log_serror(LOG_MARK, LOG_DEBUG, APR::Const::EGENERAL...)';
+ if (APACHE24) {
+ $s->loglevel($orig_log_level);
+ }
+ }
+
+ # log_rerror
+ t_server_log_error_is_expected();
+ $r->log_rerror(Apache2::Log::LOG_MARK, Apache2::Const::LOG_CRIT,
+ APR::Const::ENOTIME, "log_rerror test");
+ # can't match against the error string, since a locale may kick in
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:crit\] \[pid[^]]+\] .*?: \[[^]]+\] log_rerror test/,
+ '$r->log_rerror(LOG_MARK, LOG_CRIT, APR::Const::ENOTIME...)';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[crit\] .*?: log_rerror test/,
+ '$r->log_rerror(LOG_MARK, LOG_CRIT, APR::Const::ENOTIME...)';
+ }
+
+ # log_error
+ {
+ t_server_log_error_is_expected();
+ $r->log_error('$r->log_error test');
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:error\] \[pid[^]]+\] \$r->log_error test/,
+ '$r->log_error(...)';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[error\] \$r->log_error test/,
+ '$r->log_error(...)';
+ }
+
+ t_server_log_error_is_expected();
+ $s->log_error('$s->log_error test');
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:error\] \[pid[^]]+\] \$s->log_error test/,
+ '$s->log_error(...)';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[error\] \$s->log_error test/,
+ '$s->log_error(...)';
+ }
+ }
+
+ # log_reason
+ {
+ t_server_log_error_is_expected();
+ $r->log_reason('$r->log_reason test');
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:error\] \[pid[^]]+\] access to.*failed.*reason: \$r->log_reason test/,
+ '$r->log_reason(msg)';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[error\] access to.*failed.*reason: \$r->log_reason test/,
+ '$r->log_reason(msg)';
+ }
+
+ t_server_log_error_is_expected();
+ $r->log_reason('$r->log_reason filename test','filename');
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:error\] \[pid[^]]+\] access to filename failed.*\$r->log_reason filename test/,
+ '$r->log_reason(msg, filename)';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[error\] access to filename failed.*\$r->log_reason filename test/,
+ '$r->log_reason(msg, filename)';
+ }
+ }
+
+ # XXX: at the moment we can't change loglevel after server startup
+ # in a threaded mpm environment
+ if (!Apache2::MPM->is_threaded) {
+ my $orig_log_level = $s->loglevel;
+
+ $s->loglevel(Apache2::Const::LOG_INFO);
+
+ if ($s->error_fname) {
+ #XXX: does not work under t/TEST -ssl
+ $slog->debug(sub { die "set loglevel no workie" });
+ # ok t_cmp $logdiff->diff...
+ }
+
+ t_server_log_warn_is_expected();
+ $s->loglevel(Apache2::Const::LOG_DEBUG);
+ $slog->debug(sub { ok 1; "$package test done" });
+ ok t_cmp $logdiff->diff,
+ qr/TestAPI::aplog test done/,
+ '$slog->debug(sub { })';
+
+ $s->loglevel($orig_log_level);
+ }
+ else {
+ ok 1;
+ ok 1;
+ }
+
+ # notice() messages ignore the LogLevel value and always get
+ # logged by Apache design (unless error log is set to syslog)
+ if (!Apache2::MPM->is_threaded) {
+ my $orig_log_level = $s->loglevel;
+
+ $r->server->loglevel(Apache2::Const::LOG_ERR);
+ my $ignore = $logdiff->diff; # reset fh
+ # notice < error
+ my $msg = "This message should appear with LogLevel=error!";
+ $r->log->notice($msg);
+ ok t_cmp $logdiff->diff,
+ qr/[notice] .*? $msg/,
+ "notice() logs regardless of LogLevel";
+
+ $s->loglevel($orig_log_level);
+ }
+ else {
+ ok 1;
+ }
+
+
+ t_server_log_warn_is_expected();
+ $s->warn('$s->warn test');
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:warn\] \[pid[^]]+\] \$s->warn test/,
+ '$s->warn()';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[warn\] \$s->warn test/,
+ '$s->warn()';
+ }
+
+ {
+ t_server_log_warn_is_expected();
+ # this uses global server to get $s internally
+ Apache2::ServerRec::warn("Apache2::ServerRec::warn test");
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:warn\] \[pid[^]]+\] Apache2::ServerRec::warn test/,
+ 'Apache2::ServerRec::warn() w/o Apache2::RequestUtil->request ';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[warn\] Apache2::ServerRec::warn test/,
+ 'Apache2::ServerRec::warn() w/o Apache2::RequestUtil->request ';
+ }
+
+ Apache2::RequestUtil->request($r);
+ t_server_log_warn_is_expected();
+ # this uses the global $r to get $s internally
+ Apache2::ServerRec::warn("Apache2::ServerRec::warn test");
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:warn\] \[pid[^]]+\] Apache2::ServerRec::warn test/,
+ 'Apache2::ServerRec::warn() w/ Apache2::RequestUtil->request ';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[warn\] Apache2::ServerRec::warn test/,
+ 'Apache2::ServerRec::warn() w/ Apache2::RequestUtil->request ';
+ }
+ }
+
+ t_server_log_warn_is_expected();
+ warn "warn test";
+ if (APACHE24) {
+ ok t_cmp $logdiff->diff,
+ qr/\[\w*:warn\] \[pid[^]]+\] warn test/,
+ 'overriden via export warn()';
+ }
+ else {
+ ok t_cmp $logdiff->diff,
+ qr/\[warn\] warn test/,
+ 'overriden via export warn()';
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/command.pm b/2_0_13/t/response/TestAPI/command.pm
new file mode 100644
index 0000000..db32ea1
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/command.pm
@@ -0,0 +1,43 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::command;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Command ();
+use Apache2::Module ();
+
+use Apache2::Const -compile => qw(OK ITERATE OR_ALL);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 6;
+
+ my $mod_perl_module = Apache2::Module::find_linked_module('mod_perl.c');
+
+ ok $mod_perl_module;
+
+ my $cmd = $mod_perl_module->cmds;
+
+ ok defined $cmd;
+
+ ok UNIVERSAL::isa($cmd, 'Apache2::Command');
+
+ while ($cmd) {
+ if ($cmd->name eq 'PerlResponseHandler') {
+ ok t_cmp($cmd->args_how, Apache2::Const::ITERATE, 'args_how');
+ ok t_cmp($cmd->errmsg, qr/Subroutine name/, 'errmsg');
+ ok t_cmp($cmd->req_override, Apache2::Const::OR_ALL, 'req_override');
+ last;
+ }
+ $cmd = $cmd->next;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/conn_rec.pm b/2_0_13/t/response/TestAPI/conn_rec.pm
new file mode 100644
index 0000000..a561629
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/conn_rec.pm
@@ -0,0 +1,96 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::conn_rec;
+
+# this test module is only for testing fields in the conn_rec listed
+# in apache_structures.map (but some fields are tested in other tests)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::Connection ();
+
+use Apache2::Const -compile => qw(OK CONN_CLOSE);
+
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+sub handler {
+ my $r = shift;
+
+ my $c = $r->connection;
+
+ plan $r, tests => 16;
+
+ ok $c;
+
+ ok $c->pool->isa('APR::Pool');
+
+ ok $c->base_server->isa('Apache2::ServerRec');
+
+ ok $c->client_socket->isa('APR::Socket');
+
+ ok $c->local_addr->isa('APR::SockAddr');
+
+ if (APACHE24) {
+ ok $c->client_addr->isa('APR::SockAddr');
+
+ # client_ip
+ {
+ my $client_ip_org = $c->client_ip;
+ my $client_ip_new = "10.10.10.255";
+ ok $client_ip_org;
+
+ $c->client_ip($client_ip_new);
+ ok t_cmp $c->client_ip, $client_ip_new;
+
+ # restore
+ $c->client_ip($client_ip_org);
+ ok t_cmp $c->client_ip, $client_ip_org;
+ }
+ }
+ else {
+ ok $c->remote_addr->isa('APR::SockAddr');
+ # remote_ip
+ {
+ my $remote_ip_org = $c->remote_ip;
+ my $remote_ip_new = "10.10.10.255";
+ ok $remote_ip_org;
+
+ $c->remote_ip($remote_ip_new);
+ ok t_cmp $c->remote_ip, $remote_ip_new;
+
+
+ # restore
+ $c->remote_ip($remote_ip_org);
+ ok t_cmp $c->remote_ip, $remote_ip_org;
+ }
+ }
+
+ ok $c->remote_host || 1;
+
+ ok !$c->aborted;
+
+ ok t_cmp($c->keepalive,
+ Apache2::Const::CONN_CLOSE,
+ "the client has issued a non-keepalive request");
+
+ ok $c->local_ip;
+
+ ok $c->local_host || 1;
+
+ t_debug "id ", ($c->id == 0 ? "zero" : $c->id);
+ ok $c->id || 1;
+
+ ok $c->notes;
+
+ # XXX: missing tests
+ # conn_config
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/conn_util.pm b/2_0_13/t/response/TestAPI/conn_util.pm
new file mode 100644
index 0000000..b3e167f
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/conn_util.pm
@@ -0,0 +1,38 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::conn_util;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::Connection ();
+
+use Apache2::Const -compile => qw(OK REMOTE_HOST REMOTE_NAME
+ REMOTE_NOLOOKUP REMOTE_DOUBLE_REV);
+
+sub handler {
+ my $r = shift;
+
+ my $c = $r->connection;
+
+ plan $r, tests => 7;
+
+ ok $c->get_remote_host() || 1;
+
+ for (Apache2::Const::REMOTE_HOST, Apache2::Const::REMOTE_NAME,
+ Apache2::Const::REMOTE_NOLOOKUP, Apache2::Const::REMOTE_DOUBLE_REV) {
+ ok $c->get_remote_host($_) || 1;
+ }
+
+ ok $c->get_remote_host(Apache2::Const::REMOTE_HOST,
+ $r->per_dir_config) || 1;
+ ok $c->get_remote_host(Apache2::Const::REMOTE_HOST, $r->per_dir_config) || 1;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/content_encoding.pm b/2_0_13/t/response/TestAPI/content_encoding.pm
new file mode 100644
index 0000000..a405000
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/content_encoding.pm
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::content_encoding;
+
+# tests: $r->content_encoding("gzip");
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK DECLINED M_POST);
+
+sub handler {
+ my $r = shift;
+
+ return Apache2::Const::DECLINED unless $r->method_number == Apache2::Const::M_POST;
+
+ my $data = TestCommon::Utils::read_post($r);
+
+ require Compress::Zlib;
+
+ $r->content_type("text/plain");
+ $r->content_encoding("gzip");
+
+ $r->print(Compress::Zlib::memGzip($data));
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestAPI/custom_response.pm b/2_0_13/t/response/TestAPI/custom_response.pm
new file mode 100644
index 0000000..b7dc429
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/custom_response.pm
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::custom_response;
+
+# custom_response() doesn't alter the response code, but is used to
+# replace the standard response body
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Response ();
+
+use Apache2::Const -compile => qw(FORBIDDEN);
+
+sub handler {
+ my $r = shift;
+
+ my $how = $r->args || '';
+ # warn "$how";
+ # could be text or url
+ $r->custom_response(Apache2::Const::FORBIDDEN, $how);
+
+ return Apache2::Const::FORBIDDEN;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<Location /TestAPI__custom_response>
+ AuthName dummy
+ AuthType none
+ PerlAccessHandler TestAPI::custom_response
+</Location>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/response/TestAPI/err_headers_out.pm b/2_0_13/t/response/TestAPI/err_headers_out.pm
new file mode 100644
index 0000000..c8447ab
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/err_headers_out.pm
@@ -0,0 +1,31 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::err_headers_out;
+
+# tests: $r->err_headers_out
+
+# when sending a non-2xx response one must use $r->err_headers_out to
+# set extra headers
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use APR::Table ();
+
+use Apache2::Const -compile => qw(OK NOT_FOUND);
+
+sub handler {
+ my $r = shift;
+
+ # this header will always make it to the client
+ $r->err_headers_out->add('X-err_headers_out' => "err_headers_out");
+
+ # this header will make it to the client only on 2xx response
+ $r->headers_out->add('X-headers_out' => "headers_out");
+
+ return $r->args eq "404" ? Apache2::Const::NOT_FOUND : Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestAPI/in_out_filters.pm b/2_0_13/t/response/TestAPI/in_out_filters.pm
new file mode 100644
index 0000000..1bb03a2
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/in_out_filters.pm
@@ -0,0 +1,84 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::in_out_filters;
+
+# testing: $r->input_filters and $r->output_filters
+# it's possible to read a POST data and send a response body w/o using
+# $r->read/$r->print
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+
+use APR::Brigade ();
+use APR::Bucket ();
+use Apache2::Filter ();
+
+use Apache2::Const -compile => qw(OK M_POST DECLINED MODE_READBYTES);
+use APR::Const -compile => qw(SUCCESS BLOCK_READ);
+
+use constant IOBUFSIZE => 8192;
+
+sub handler {
+ my $r = shift;
+
+ return Apache2::Const::DECLINED unless $r->method_number == Apache2::Const::M_POST;
+
+ $r->content_type("text/plain");
+
+ my $data = read_request_body($r);
+ send_response_body($r, lc($data));
+
+ Apache2::Const::OK;
+}
+
+sub send_response_body {
+ my ($r, $data) = @_;
+
+ my $bb = APR::Brigade->new($r->pool,
+ $r->connection->bucket_alloc);
+
+ my $b = APR::Bucket->new($r->connection->bucket_alloc, $data);
+ $bb->insert_tail($b);
+ $r->output_filters->fflush($bb);
+ $bb->destroy;
+}
+
+sub read_request_body {
+ my $r = shift;
+
+ my $bb = APR::Brigade->new($r->pool,
+ $r->connection->bucket_alloc);
+
+ my $data = '';
+ my $seen_eos = 0;
+ my $count = 0;
+ do {
+ $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
+ APR::Const::BLOCK_READ, IOBUFSIZE);
+
+ $count++;
+
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ if ($b->is_eos) {
+ $seen_eos++;
+ last;
+ }
+
+ if ($b->read(my $buf)) {
+ $data .= $buf;
+ }
+
+ $b->delete;
+ }
+
+ } while (!$seen_eos);
+
+ $bb->destroy;
+
+ return $data;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestAPI/internal_redirect.pm b/2_0_13/t/response/TestAPI/internal_redirect.pm
new file mode 100644
index 0000000..1918f3b
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/internal_redirect.pm
@@ -0,0 +1,66 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::internal_redirect;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => 'OK';
+
+sub modperl {
+ my $r = shift;
+
+ my %args = map { split('=', $_, 2) } split /[&]/, $r->args;
+ if ($args{main}) {
+ # sub-req
+ $r->content_type('text/plain');
+ debug "modperl: sub-req: response";
+ $r->print("internal redirect: $args{main} => modperl");
+ }
+ else {
+ # main-req
+ my $redirect_uri = $args{uri};
+ debug "modperl: main-req => $redirect_uri?main=modperl";
+ $r->internal_redirect("$redirect_uri?main=modperl");
+ }
+
+ Apache2::Const::OK;
+}
+
+sub perl_script {
+ my $r = shift;
+
+ my %args = map { split('=', $_, 2) } split /[&]/, $r->args;
+ if ($args{main}) {
+ # sub-req
+ $r->content_type('text/plain');
+ debug "perl-script: sub-req: response";
+ print "internal redirect: $args{main} => perl-script";
+ }
+ else {
+ # main-req
+ my $redirect_uri = $args{uri};
+ debug "perl-script: main-req => $redirect_uri?main=perl-script";
+ $r->internal_redirect("$redirect_uri?main=perl-script");
+ }
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+<NoAutoConfig>
+ PerlModule TestAPI::internal_redirect
+ <Location /TestAPI__internal_redirect_modperl>
+ SetHandler modperl
+ PerlResponseHandler TestAPI::internal_redirect::modperl
+ </Location>
+ <Location /TestAPI__internal_redirect_perl_script>
+ SetHandler perl-script
+ PerlResponseHandler TestAPI::internal_redirect::perl_script
+ </Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/internal_redirect_handler.pm b/2_0_13/t/response/TestAPI/internal_redirect_handler.pm
new file mode 100644
index 0000000..8bab332
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/internal_redirect_handler.pm
@@ -0,0 +1,39 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::internal_redirect_handler;
+
+# $r->internal_redirect_handler() is the same as
+# $r->internal_redirect() but it uses the same content-type as the
+# top-level handler
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache2::Const -compile => 'OK';
+
+my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+sub handler {
+ my $r = shift;
+
+ my %args = map { split '=', $_, 2 } split /[&]/, $r->args;
+ if ($args{main}) {
+ # sub-req should see the same content-type as the top-level
+ my $ct = $r->content_type;
+ $r->content_type('text/plain');
+ $r->print($ct);
+ }
+ else {
+ # main-req
+ $r->content_type($args{ct});
+ $r->internal_redirect_handler("$uri?main=1");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
diff --git a/2_0_13/t/response/TestAPI/lookup_misc.pm b/2_0_13/t/response/TestAPI/lookup_misc.pm
new file mode 100644
index 0000000..57d39d3
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/lookup_misc.pm
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::lookup_misc;
+
+# testing misc lookup_ methods. TestAPI::lookup_uri includes the tests
+# for lookup_uri and for filters, which should be the same for all
+# other lookup_ methods
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+use Apache2::SubRequest ();
+use Apache2::URI ();
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => 'OK';
+
+my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+sub handler {
+ my $r = shift;
+
+ my %args = map { split '=', $_, 2 } split /;/, $r->args;
+
+ if ($args{subreq} eq 'lookup_file') {
+ Apache2::URI::unescape_url($args{file});
+ debug "lookup_file($args{file})";
+ my $subr = $r->lookup_file($args{file});
+ $subr->run;
+ }
+ elsif ($args{subreq} eq 'lookup_method_uri') {
+ debug "lookup_method_uri($args{uri})";
+ my $subr = $r->lookup_method_uri("GET", $args{uri});
+ $subr->run;
+ }
+ else {
+ $r->print("default");
+ }
+
+
+ Apache2::Const::OK;
+}
+
+
+1;
+__DATA__
+<Location /lookup_method_uri>
+ SetHandler modperl
+ PerlResponseHandler Apache::TestHandler::ok
+</Location>
diff --git a/2_0_13/t/response/TestAPI/lookup_uri.pm b/2_0_13/t/response/TestAPI/lookup_uri.pm
new file mode 100644
index 0000000..17fd9d2
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/lookup_uri.pm
@@ -0,0 +1,85 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::lookup_uri;
+
+# tests $r->lookup_uri and its work with filters
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Filter ();
+use Apache2::SubRequest ();
+
+use Apache2::Const -compile => 'OK';
+
+my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+sub handler {
+ my $r = shift;
+
+ my $args = $r->args || '';
+ my %args = map { split '=', $_, 2 } split /;/, $args;
+
+ if ($args{main}) {
+ $args =~ s/main=1;//;
+ $r->print($args);
+ }
+ else {
+ my $new_args = "$uri?main=1;$args";
+ my $subr;
+ $args{filter} ||= '';
+ if ($args{filter} eq 'first') {
+ # run all request filters
+ $subr = $r->lookup_uri($new_args,
+ $r->output_filters);
+ }
+ elsif ($args{filter} eq 'second') {
+ # run all request filters, but the top one
+ $subr = $r->lookup_uri($new_args,
+ $r->output_filters->next);
+ }
+ elsif ($args{filter} eq 'default') {
+ # run none of request filters
+ $subr = $r->lookup_uri($new_args);
+ }
+ elsif ($args{filter} eq 'none') {
+ # run none of request filters
+ $subr = $r->lookup_uri($new_args,
+ $r->proto_output_filters);
+ }
+ else {
+ die "no filter= argument was received";
+ }
+
+ $subr->run;
+ }
+
+ Apache2::Const::OK;
+}
+
+sub prefix_filter {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print("pre+$buffer");
+ }
+
+ Apache2::Const::OK;
+}
+
+sub suffix_filter {
+ my $filter = shift;
+
+ while ($filter->read(my $buffer, 1024)) {
+ $filter->print("$buffer+suf");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlModule TestAPI::lookup_uri
+PerlOutputFilterHandler TestAPI::lookup_uri::prefix_filter
+PerlOutputFilterHandler TestAPI::lookup_uri::suffix_filter
diff --git a/2_0_13/t/response/TestAPI/lookup_uri2.pm b/2_0_13/t/response/TestAPI/lookup_uri2.pm
new file mode 100644
index 0000000..c167210
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/lookup_uri2.pm
@@ -0,0 +1,59 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::lookup_uri2;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::SubRequest ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+
+use Apache2::Const -compile => 'OK';
+
+sub myplan {
+ my $r = shift;
+
+ $r->puts("1..3\nok 1\n");
+
+ die "must indicate a sub-request" if $r->is_initial_req();
+
+ Apache2::Const::OK;
+}
+
+sub ok3 {
+ my $r = shift;
+
+ $r->puts("ok 3\n");
+
+ Apache2::Const::OK;
+}
+
+sub subrequest {
+ my ($r, $sub) = @_;
+ (my $uri = join '::', __PACKAGE__, $sub) =~ s!::!__!g;
+ $r->lookup_uri($uri)->run;
+}
+
+sub handler {
+ my $r = shift;
+
+ subrequest($r, 'myplan');
+
+ $r->puts("ok 2\n");
+
+ subrequest($r, 'ok3');
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<Location /TestAPI__lookup_uri2__myplan>
+ SetHandler modperl
+ PerlResponseHandler TestAPI::lookup_uri2::myplan
+</Location>
+
+<Location /TestAPI__lookup_uri2__ok3>
+ SetHandler modperl
+ PerlResponseHandler TestAPI::lookup_uri2::ok3
+</Location>
diff --git a/2_0_13/t/response/TestAPI/module.pm b/2_0_13/t/response/TestAPI/module.pm
new file mode 100644
index 0000000..4d0754f
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/module.pm
@@ -0,0 +1,98 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::module;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestConfig;
+use Apache::TestUtil;
+use Apache2::BuildConfig;
+
+use Apache2::Module ();
+use DynaLoader ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $cfg = Apache::Test::config();
+
+ my $top_module = Apache2::Module::top_module();
+
+ my $module_count = 0;
+ for (my $modp = $top_module; $modp; $modp = $modp->next) {
+ $module_count++;
+ }
+
+ my $tests = 12 + ( 5 * $module_count );
+
+ plan $r, tests => $tests;
+
+ my $core = Apache2::Module::find_linked_module('core.c');
+ ok defined $core && $core->name eq 'core.c';
+
+ #.c
+ ok t_cmp Apache2::Module::loaded('mod_perl.c'), 1,
+ "Apache2::Module::loaded('mod_perl.c')";
+
+ ok t_cmp Apache2::Module::loaded('Apache__Module_foo.c'), 0,
+ "Apache2::Module::loaded('Apache__Module_foo.c')";
+
+ #.so
+ {
+ my $build = Apache2::BuildConfig->new;
+ my $expect = $build->should_build_apache ? 0 : 1;
+ ok t_cmp Apache2::Module::loaded('mod_perl.so'), $expect,
+ "Apache2::Module::loaded('mod_perl.so')";
+ }
+
+ ok t_cmp Apache2::Module::loaded('Apache__Module__foo.so'), 0,
+ "Apache2::Module::loaded('Apache__Module_foo.so')";
+
+ #perl
+ {
+ ok t_cmp Apache2::Module::loaded('Apache2::Module'), 1,
+ "Apache2::Module::loaded('Apache2::Module')";
+
+ ok t_cmp Apache2::Module::loaded('Apache__Module_foo'), 0,
+ "Apache2::Module::loaded('Apache__Module_foo')";
+
+ # TestAPI::module::foo wasn't loaded but the stash exists
+ $TestAPI::module::foo::test = 1;
+ ok t_cmp Apache2::Module::loaded('TestAPI::module::foo'), 0,
+ "Apache2::Module::loaded('TestAPI::module::foo')";
+
+ # module TestAPI wasn't loaded but the stash exists, since
+ # TestAPI::module was loaded
+ ok t_cmp Apache2::Module::loaded('TestAPI'), 0,
+ "Apache2::Module::loaded('TestAPI')";
+ }
+
+ #bogus
+ ok t_cmp Apache2::Module::loaded('Apache__Module_foo.foo'), 0,
+ "Apache2::Module::loaded('Apache__Module_foo.foo')";
+
+ ok t_cmp Apache2::Module::loaded(''), 0,
+ "Apache2::Module::loaded('')";
+
+ ok t_cmp ref($top_module), 'Apache2::Module', 'top_module';
+
+ my $mmn_major = $cfg->{httpd_info}{MODULE_MAGIC_NUMBER_MAJOR};
+ my $mmn_minor = $cfg->{httpd_info}{MODULE_MAGIC_NUMBER_MINOR};
+ for (my $modp = $top_module; $modp; $modp = $modp->next) {
+ my $name = $modp->name;
+ ok $name;
+ t_debug("Testing module: " . $modp->name);
+ ok t_cmp $modp->ap_api_major_version, $mmn_major;
+ ok $modp->ap_api_minor_version <= $mmn_minor;
+ ok $modp->module_index >= 0;
+ my $cmds = $modp->cmds;
+ ok !defined($cmds) || ref($cmds) eq 'Apache2::Command';
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/process.pm b/2_0_13/t/response/TestAPI/process.pm
new file mode 100644
index 0000000..c137646
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/process.pm
@@ -0,0 +1,40 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::process;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::ServerRec ();
+use Apache2::Process ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 4;
+
+ my $s = $r->server;
+ my $proc = $s->process;
+ ok t_cmp(1, $proc->isa('Apache2::Process'), "isa('Apache2::Process')");
+
+ my $global_pool = $proc->pool;
+ ok t_cmp(1, $global_pool->isa('APR::Pool'), "pglob isa('APR::Pool')");
+
+ my $pconf = $proc->pconf;
+ ok t_cmp(1, $pconf->isa('APR::Pool'), "pconf isa('APR::Pool')");
+
+ my $proc_name = $proc->short_name;
+ t_debug($proc_name);
+ ok $proc_name;
+
+ Apache2::Const::OK;
+}
+
+1;
+
+__END__
diff --git a/2_0_13/t/response/TestAPI/query.pm b/2_0_13/t/response/TestAPI/query.pm
new file mode 100644
index 0000000..78f1148
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/query.pm
@@ -0,0 +1,152 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::query;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::MPM ();
+
+use Apache2::Const -compile => qw(OK :mpmq);
+
+sub handler {
+
+ my $r = shift;
+
+ plan $r, tests => 5;
+
+ # ok, this isn't particularly pretty, but I can't think
+ # of a better way to do it
+ # all of these attributes I pulled right from the C sources
+ # so if, say, leader all of a sudden changes its properties,
+ # these tests will fail
+
+ my $mpm = lc Apache2::MPM->show;
+
+ if ($mpm eq 'prefork') {
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_NOT_SUPPORTED,
+ "MPMQ_IS_THREADED ($mpm)");
+
+ # is_threaded() is just a constsub set to the result from
+ # ap_mpm_query(AP_MPMQ_IS_THREADED)
+
+ ok t_cmp($query,
+ Apache2::MPM->is_threaded,
+ "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)");
+
+ t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded);
+ ok (! Apache2::MPM->is_threaded);
+ }
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_DYNAMIC,
+ "MPMQ_IS_FORKED ($mpm)");
+ }
+
+ }
+ elsif ($mpm eq 'worker') {
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_STATIC,
+ "MPMQ_IS_THREADED ($mpm)");
+
+ ok t_cmp($query,
+ Apache2::MPM->is_threaded,
+ "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)");
+
+ t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded);
+ ok (Apache2::MPM->is_threaded);
+ }
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_DYNAMIC,
+ "MPMQ_IS_FORKED ($mpm)");
+ }
+ }
+ elsif ($mpm eq 'leader') {
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_STATIC,
+ "MPMQ_IS_THREADED ($mpm)");
+
+ ok t_cmp($query,
+ Apache2::MPM->is_threaded,
+ "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)");
+
+ t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded);
+ ok (Apache2::MPM->is_threaded);
+ }
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_DYNAMIC,
+ "MPMQ_IS_FORKED ($mpm)");
+ }
+ }
+ elsif ($mpm eq 'winnt') {
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_STATIC,
+ "MPMQ_IS_THREADED ($mpm)");
+
+ ok t_cmp($query,
+ Apache2::MPM->is_threaded,
+ "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)");
+
+ t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded);
+ ok (Apache2::MPM->is_threaded);
+ }
+
+ {
+ my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED);
+
+ ok t_cmp($query,
+ Apache2::Const::MPMQ_NOT_SUPPORTED,
+ "MPMQ_IS_FORKED ($mpm)");
+ }
+ }
+ else {
+ skip "skipping MPMQ_IS_THREADED test for $mpm MPM", 0;
+ skip "skipping Apache2::MPM->is_threaded equivalence test for $mpm MPM", 0;
+ skip "skipping MPMQ_IS_FORKED test for $mpm MPM", 0;
+ skip "skipping Apache2::MPM->is_threaded test for $mpm MPM", 0;
+ }
+
+ # make sure that an undefined MPMQ constant yields undef
+ {
+ my $query = Apache2::MPM->query(72);
+
+ ok t_cmp($query,
+ undef,
+ "unknown MPMQ value returns undef");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/request_rec.pm b/2_0_13/t/response/TestAPI/request_rec.pm
new file mode 100644
index 0000000..d5bfe52
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/request_rec.pm
@@ -0,0 +1,278 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::request_rec;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+
+use APR::Finfo ();
+use APR::Pool ();
+
+use Apache2::Const -compile => qw(OK M_GET M_PUT);
+use APR::Const -compile => qw(FINFO_SIZE);
+
+#this test module is only for testing fields in the request_rec
+#listed in apache_structures.map
+#XXX: GloabalRequest test should be moved elsewhere
+# as should $| test
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 55;
+
+ #Apache2::RequestUtil->request($r); #PerlOptions +GlobalRequest takes care
+ my $gr = Apache2::RequestUtil->request;
+
+ ok $$gr == $$r;
+
+ my $newr = Apache2::RequestRec->new($r->connection, $r->pool);
+ Apache2::RequestUtil->request($newr);
+ $gr = Apache2::RequestUtil->request;
+
+ ok $$gr == $$newr;
+
+ Apache2::RequestUtil->request($r);
+
+ ok $r->pool->isa('APR::Pool');
+
+ ok $r->connection->isa('Apache2::Connection');
+
+ ok $r->server->isa('Apache2::ServerRec');
+
+ for (qw(next prev main)) {
+ ok (! $r->$_()) || $r->$_()->isa('Apache2::RequestRec');
+ }
+
+ ok !$r->assbackwards;
+
+ ok !$r->proxyreq; # see also TestModules::proxy
+
+ ok !$r->header_only;
+
+ ok $r->protocol =~ /http/i;
+
+ # LWP >=6.00 uses HTTP/1.1, other HTTP/1.0
+ ok t_cmp $r->proto_num, 1000+substr($r->the_request, -1),
+ 't->proto_num';
+
+ ok t_cmp lc($r->hostname), lc($r->get_server_name), '$r->hostname';
+
+ {
+ my $old_hostname = $r->hostname("other.hostname");
+ ok t_cmp $r->hostname, "other.hostname", '$r->hostname rw';
+ $r->hostname($old_hostname);
+ }
+
+ ok $r->request_time;
+
+ ok $r->status_line || 1;
+
+ ok $r->status || 1;
+
+ ok t_cmp $r->method, 'GET', '$r->method';
+
+ ok t_cmp $r->method_number, Apache2::Const::M_GET, '$r->method_number';
+
+ ok $r->headers_in;
+
+ ok $r->headers_out;
+
+ # tested in TestAPI::err_headers_out
+ ok $r->err_headers_out;
+
+ ok $r->subprocess_env;
+
+ ok $r->notes;
+
+ ok $r->content_type;
+
+ ok $r->handler;
+
+ ok $r->ap_auth_type || 1;
+
+ ok $r->no_cache || 1;
+
+ ok !$r->no_local_copy;
+
+ {
+ local $| = 0;
+ ok t_cmp $r->print("# buffered\n"), 11, "buffered print";
+ ok t_cmp $r->print(), "0E0", "buffered print";
+
+ local $| = 1;
+ my $string = "# not buffered\n";
+ ok t_cmp $r->print(split //, $string), length($string),
+ "unbuffered print";
+ }
+
+ # GET header components
+ {
+ my $args = "my_args=3";
+ my $path_info = "/my_path_info";
+ my $base_uri = "/TestAPI__request_rec";
+
+ ok t_cmp $r->unparsed_uri, "$base_uri$path_info?$args";
+
+ ok t_cmp $r->uri, "$base_uri$path_info", '$r->uri';
+
+ ok t_cmp $r->path_info, $path_info, '$r->path_info';
+
+ ok t_cmp $r->args, $args, '$r->args';
+
+ # LWP uses HTTP/1.1 since 6.00
+ ok t_cmp $r->the_request, qr!GET
+ \x20
+ \Q$base_uri$path_info\E\?\Q$args\E
+ \x20
+ HTTP/1\.\d!x,
+ '$r->the_request';
+
+ {
+ my $new_request = "GET $base_uri$path_info?$args&foo=bar HTTP/1.0";
+ my $old_request = $r->the_request($new_request);
+ ok t_cmp $r->the_request, $new_request, '$r->the_request rw';
+ $r->the_request($old_request);
+ }
+
+ ok $r->filename;
+
+ my $location = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+ ok t_cmp $r->location, $location, '$r->location';
+ }
+
+ # bytes_sent
+ {
+ $r->rflush;
+ my $sent = $r->bytes_sent;
+ t_debug "sent so far: $sent bytes";
+ # at least 100 chars were sent already
+ ok $sent > 100;
+ }
+
+ # mtime
+ {
+ my $mtime = (stat __FILE__)[9];
+ $r->mtime($mtime);
+ ok t_cmp $r->mtime, $mtime, "mtime";
+ }
+
+ # finfo
+ {
+ my $size = (stat __FILE__)[7];
+ my $finfo = APR::Finfo::stat(__FILE__, APR::Const::FINFO_SIZE, $r->pool);
+ $r->finfo($finfo);
+ # just one field test, all accessors are fully tested in
+ # TestAPR::finfo
+ ok t_cmp($r->finfo->size,
+ $size,
+ '$r->finfo');
+ }
+
+ # allowed
+ {
+ $r->allowed(1 << Apache2::Const::M_GET);
+
+ ok $r->allowed & (1 << Apache2::Const::M_GET);
+ ok ! ($r->allowed & (1 << Apache2::Const::M_PUT));
+
+ $r->allowed($r->allowed | (1 << Apache2::Const::M_PUT));
+ ok $r->allowed & (1 << Apache2::Const::M_PUT);
+ }
+
+ # content_languages
+ {
+ my $def = [qw(fr)]; #default value
+ my $l = [qw(fr us cn)]; #new value
+
+ if (have_module('mod_mime')) {
+ ok t_cmp $r->content_languages, $def, '$r->content_languages';
+ }
+ else {
+ skip "Need mod_mime", 0;
+ }
+
+ my $old = $r->content_languages($l);
+ if (have_module('mod_mime')) {
+ ok t_cmp $old, $def, '$r->content_languages';
+ }
+ else {
+ skip "Need mod_mime", 0;
+ }
+
+ ok t_cmp $r->content_languages, $l, '$r->content_languages';
+
+ eval { $r->content_languages({}) };
+ ok t_cmp $@, qr/Not an array reference/,
+ '$r->content_languages(invalid)';
+ }
+
+ ### invalid $r
+ {
+ my $r = bless {}, "Apache2::RequestRec";
+ my $err = q[method `uri' invoked by a `Apache2::RequestRec' ] .
+ q[object with no `r' key!];
+ eval { $r->uri };
+ ok t_cmp $@, qr/$err/, "invalid $r object";
+ }
+ {
+ my $r = bless {}, "NonExisting";
+ my $err = q[method `uri' invoked by a `NonExisting' ] .
+ q[object with no `r' key!];
+ eval { Apache2::RequestRec::uri($r) };
+ ok t_cmp $@, qr/$err/, "invalid $r object";
+ }
+ {
+ my $r = {};
+ my $err = q[method `uri' invoked by a `unknown' ] .
+ q[object with no `r' key!];
+ eval { Apache2::RequestRec::uri($r) };
+ ok t_cmp $@, qr/$err/, "invalid $r object";
+ }
+
+ # out-of-scope pools
+ {
+ my $newr = Apache2::RequestRec->new($r->connection, APR::Pool->new);
+ {
+ require APR::Table;
+ # try to overwrite the pool
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+ }
+ # check if $newr is still OK
+ ok $newr->connection->isa('Apache2::Connection');
+ }
+
+ # tested in other tests
+ # - input_filters: TestAPI::in_out_filters
+ # - output_filters: TestAPI::in_out_filters
+ # - per_dir_config: in several other tests
+ # - content_encoding: TestAPI::content_encoding
+ # - user: TestHooks::authz / TestHooks::authen
+
+ # XXX: untested
+ # - request_config
+ # - allowed_xmethods
+ # - allowed_methods
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<Location /TestAPI__request_rec>
+ PerlOptions +GlobalRequest
+ <IfModule mod_mime.c>
+ DefaultLanguage fr
+ </IfModule>
+ SetHandler modperl
+ PerlResponseHandler TestAPI::request_rec
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/request_subclass.pm b/2_0_13/t/response/TestAPI/request_subclass.pm
new file mode 100644
index 0000000..1b76229
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/request_subclass.pm
@@ -0,0 +1,50 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::request_subclass;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+our @ISA = qw(Apache2::RequestRec);
+
+use Apache::Test;
+use Apache::TestRequest;
+
+use Apache2::Const -compile => 'OK';
+
+sub new {
+ my $class = shift;
+ my $r = shift;
+ bless { r => $r }, $class;
+}
+
+my $location = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+sub handler {
+ my $r = __PACKAGE__->new(shift);
+
+ plan $r, tests => 5;
+
+ eval { my $gr = Apache2::RequestUtil->request; };
+ ok $@;
+
+ ok $r->uri eq $location;
+
+ ok ((bless { r => $r })->uri eq $location); #nested
+
+ eval { (bless {})->uri };
+
+ ok $@ =~ /no .* key/;
+
+ eval { (bless [])->uri };
+
+ ok $@ =~ /unsupported/;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlOptions -GlobalRequest
diff --git a/2_0_13/t/response/TestAPI/request_util.pm b/2_0_13/t/response/TestAPI/request_util.pm
new file mode 100644
index 0000000..2af76fe
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/request_util.pm
@@ -0,0 +1,93 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::request_util;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestUtil ();
+use Apache2::MPM ();
+use Apache2::Log ();
+use APR::Pool ();
+
+use Apache2::Const -compile => 'OK';
+
+my %status_lines = (
+ 200 => '200 OK',
+ 400 => '400 Bad Request',
+ 500 => '500 Internal Server Error',
+);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => (scalar keys %status_lines) + 11;
+
+ # default_type() is gone as of httpd 2.3.2-dev
+ ok !defined(&Apache2::RequestRec::default_type) || $r->default_type;
+
+ my $document_root = $r->document_root;
+
+ ok $document_root;
+
+ if (!Apache2::MPM->is_threaded) {
+ my $path_orig = my $path = '/tmp/foo';
+ ok t_cmp($document_root, $r->document_root($path));
+ # make sure that the new docroot string is copied internally,
+ # and later manipulations of the passed scalar don't affect it
+ $path .= "suffix";
+ ok t_cmp($path_orig, $r->document_root($document_root));
+ }
+ else {
+ eval { $r->document_root('/tmp/foo') };
+ ok t_cmp($@, qr/Can't run.*in the threaded env/,
+ "document_root is read-only under threads");
+ ok 1;
+ }
+
+ ok $r->get_server_name;
+
+ ok $r->get_server_port;
+
+ ok $r->get_limit_req_body || 1;
+
+ ok $r->is_initial_req;
+
+ my $sig = $r->psignature("Here is the sig: ");
+ t_debug $sig;
+ ok $sig;
+
+ my $pattern =
+ qr!(?s)GET /TestAPI__request_util.*Host:.*200 OK.*Content-Type:!;
+
+ ok t_cmp($r->as_string,
+ $pattern,
+ "test for the request_line, host, status, and few " .
+ "headers that should always be there");
+
+ while (my ($code, $line) = each %status_lines) {
+ ok t_cmp(Apache2::RequestUtil::get_status_line($code),
+ $line,
+ "Apache2::RequestUtil::get_status_line($code)");
+ }
+
+ if (Apache2::MPM->is_threaded) {
+ eval { $r->child_terminate() };
+ ok t_cmp($@, qr/Can't run.*in a threaded mpm/, "child_terminate");
+ }
+ else {
+ t_server_log_error_is_expected();
+ ok $r->child_terminate() || 1;
+ $r->pool->cleanup_register(
+ sub {
+ my $r = shift;
+ $r->log_error("Process $$ terminates itself\n");
+ }, $r);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/response.pm b/2_0_13/t/response/TestAPI/response.pm
new file mode 100644
index 0000000..352ced7
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/response.pm
@@ -0,0 +1,54 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::response;
+
+# testing Apache2::Response methods
+#
+# XXX: a proper test is needed (at the moment just test that methods
+# can be invoked as documented)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::Response ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 7;
+
+ my $etag = $r->make_etag();
+ t_debug $etag;
+ ok $etag;
+
+ $r->set_content_length(0);
+
+ ok 1;
+
+ ok $r->meets_conditions || 1;
+
+ ok $r->rationalize_mtime(time) >= $r->request_time;
+
+ my $mtime = (stat __FILE__)[9];
+
+ $r->update_mtime($mtime);
+
+ ok $r->mtime == $mtime;
+
+ ok $r->set_keepalive() || 1;
+
+ $r->set_last_modified;
+
+ # $r->custom_response() is tested in TestAPI::custom_response
+
+ ok 1;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/rflush.pm b/2_0_13/t/response/TestAPI/rflush.pm
new file mode 100644
index 0000000..41df75d
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/rflush.pm
@@ -0,0 +1,79 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::rflush;
+
+use strict;
+use warnings FATAL => 'all';
+
+# this test verifies that rflush flushes bucket brigades
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Filter ();
+
+use Apache2::Const -compile => qw(OK);
+
+use constant READ_SIZE => 1024;
+
+sub bracket {
+ my $filter = shift;
+
+ my $data = '';
+
+ while ($filter->read(my $buffer, 1024)) {
+ $data .= $buffer;
+ }
+
+ $filter->print("[$data]") if $data;
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my $args = $r->args || '';
+ if ($args eq 'nontied') {
+ # print is now unbuffered
+ local $| = 1;
+ $r->print("1"); # send the data in the buffer + flush bucket
+ $r->print("2"); # send the data in the buffer + flush bucket
+
+ # print is now buffered
+ local $| = 0;
+ $r->print("3");
+ $r->rflush; # send the data in the buffer + flush bucket
+ $r->print("4");
+ $r->rflush; # send the data in the buffer + flush bucket
+ $r->print("5");
+ $r->print("6"); # send the data in the buffer (end of handler)
+ }
+ elsif ($args eq 'tied') {
+ my $oldfh;
+ # print is now unbuffered ("rflush"-like functionality is
+ # called internally)
+ $oldfh = select(STDOUT); $| = 1; select($oldfh);
+ print "1"; # send the data in the buffer + flush bucket
+ print "2";
+
+ # print is now buffered
+ $oldfh = select(STDOUT); $| = 0; select($oldfh);
+ print "3";
+ print "4";
+ print "5";
+ print "6"; # send the data in the buffer (end of handler)
+ }
+
+ Apache2::Const::OK;
+}
+1;
+__DATA__
+SetHandler perl-script
+PerlModule TestAPI::rflush
+PerlResponseHandler TestAPI::rflush::response
+PerlOutputFilterHandler TestAPI::rflush::bracket
diff --git a/2_0_13/t/response/TestAPI/sendfile.pm b/2_0_13/t/response/TestAPI/sendfile.pm
new file mode 100644
index 0000000..17f445a
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/sendfile.pm
@@ -0,0 +1,49 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::sendfile;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use APR::Const -compile => 'SUCCESS';
+use Apache2::Const -compile => ':common';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ my $args = $r->args;
+
+ if ($args eq 'withwrapper') {
+ # buffer output up, so we can test that sendfile flushes any
+ # buffered output before sending the file contents out
+ local $|;
+ $r->print("This is a header\n");
+ $r->sendfile(__FILE__);
+ $r->print("This is a footer\n");
+ }
+ elsif ($args eq 'offset') {
+ $r->sendfile(__FILE__, 3);
+ }
+ elsif ($args eq 'len') {
+ $r->sendfile(__FILE__, 3, 50);
+ }
+ elsif ($args eq 'noexist-n-nocheck.txt') {
+ eval { $r->sendfile($args) };
+ return int $@;
+ }
+ else {
+ my $rc = $r->sendfile($args);
+ # warn APR::Error::strerror($rc);
+ return $rc unless $rc == APR::Const::SUCCESS;
+ }
+
+ # XXX: can't quite test bogus offset and/or len, since ap_send_fd
+ # doesn't provide any error indications
+
+ return Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/server_const.pm b/2_0_13/t/response/TestAPI/server_const.pm
new file mode 100644
index 0000000..2e814ef
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/server_const.pm
@@ -0,0 +1,61 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::server_const;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use File::Spec::Functions qw(canonpath);
+
+use Apache2::ServerUtil ();
+use Apache2::Process ();
+
+use APR::Pool ();
+
+use Apache2::Const -compile => 'OK';
+
+my $cfg = Apache::Test::config;
+
+my $root = $cfg->{vars}->{serverroot};
+my $built = $cfg->{httpd_info}->{BUILT};
+my $version = $cfg->{httpd_info}->{VERSION};
+
+sub handler {
+
+ my $r = shift;
+
+ plan $r, tests => 6;
+
+ # test Apache2::ServerUtil constant subroutines
+
+ ok t_filepath_cmp(canonpath(Apache2::ServerUtil::server_root),
+ canonpath($root),
+ 'Apache2::ServerUtil::server_root()');
+
+ ok t_cmp(Apache2::ServerUtil::get_server_built,
+ $built,
+ 'Apache2::ServerUtil::get_server_built()');
+
+ my $server_descr = Apache2::ServerUtil::get_server_description;
+ ok t_cmp($server_descr, qr/^\Q$version\E/,
+ 'Apache2::ServerUtil::get_server_description()');
+
+ # added via $s->add_version_component in t/conf/modperl_extra.pl
+ ok t_cmp($server_descr, qr!\bworld domination series/2\.0\b!,
+ 'Apache2::ServerUtil::get_server_description() -- component');
+
+ # assuming ServerTokens Full (default) the banner equals description
+ ok t_cmp(Apache2::ServerUtil::get_server_banner, $server_descr,
+ 'Apache2::ServerUtil::get_server_banner()');
+
+ # version is just an alias for banner
+ ok t_cmp(Apache2::ServerUtil::get_server_version, $server_descr,
+ 'Apache2::ServerUtil::get_server_version()');
+
+ Apache2::Const::OK;
+}
+
+1;
+
+__END__
diff --git a/2_0_13/t/response/TestAPI/server_rec.pm b/2_0_13/t/response/TestAPI/server_rec.pm
new file mode 100644
index 0000000..7cd37fb
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/server_rec.pm
@@ -0,0 +1,79 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::server_rec;
+
+# this test module is only for testing fields in the server_rec listed
+# in apache_structures.map
+
+# XXX: This test needs to be mucho improved. currently it justs checks
+# whether some value is set or not
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $s = $r->server;
+
+ plan $r, tests => 20;
+
+ ok $s;
+
+ ok $s->process;
+
+ ok $s->next || 1;
+
+ ok $s->server_admin;
+
+ ok $s->server_hostname;
+
+ ok $s->port || 1;
+
+ ok $s->error_fname || 1; # vhost might not have its own (t/TEST -ssl)
+
+ # XXX: error_log;
+
+ ok $s->loglevel;
+
+ ok $s->is_virtual || 1;
+
+ # XXX: module_config
+
+ # XXX: lookup_defaults
+
+ ok $s->addrs;
+
+ t_debug("timeout : ", $s->timeout);
+ ok $s->timeout;
+
+ t_debug("keep_alive_timeout : ", $s->keep_alive_timeout);
+ ok $s->keep_alive_timeout || 1;
+ t_debug("keep_alive_max : ", $s->keep_alive_max);
+ ok $s->keep_alive_max || 1;
+ ok $s->keep_alive || 1;
+
+ ok $s->path || 1;
+
+ ok $s->names || 1;
+
+ ok $s->wild_names || 1;
+
+ ok $s->limit_req_line;
+
+ ok $s->limit_req_fieldsize;
+
+ ok $s->limit_req_fields;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/server_util.pm b/2_0_13/t/response/TestAPI/server_util.pm
new file mode 100644
index 0000000..e7d3a05
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/server_util.pm
@@ -0,0 +1,139 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::server_util;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use File::Spec::Functions qw(canonpath catfile);
+
+use Apache2::RequestRec ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Process ();
+
+use APR::Pool ();
+
+use Apache2::Const -compile => 'OK';
+
+my $serverroot = Apache::Test::config()->{vars}->{serverroot};
+
+our @ISA = qw(Apache2::RequestRec);
+
+sub new {
+ my $class = shift;
+ my $r = shift;
+ bless { r => $r }, $class;
+}
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 17;
+
+ {
+ my $s = $r->server;
+ my @expected = qw(ModPerl::Test::exit_handler TestExit::FromPerlModule::exit_handler);
+ my @handlers =
+ @{ $s->get_handlers('PerlChildExitHandler') || []};
+ ok t_cmp(scalar(@handlers), scalar(@expected), "get_handlers");
+ }
+
+ t_debug('Apache2::ServerUtil::exists_config_define');
+ ok Apache2::ServerUtil::exists_config_define('MODPERL2');
+ ok ! Apache2::ServerUtil::exists_config_define('FOO');
+
+ t_debug('registering method FOO');
+ ok $r->server->method_register('FOO');
+
+ server_root_relative_tests($r);
+
+ eval { Apache2::ServerUtil::server_shutdown_cleanup_register(
+ sub { Apache2::Const::OK });
+ };
+ my $sub = "server_shutdown_cleanup_register";
+ ok t_cmp $@, qr/Can't run '$sub' after server startup/,
+ "can't register server_shutdown cleanup after server startup";
+
+ # on start we get 1, and immediate restart gives 2
+ ok t_cmp Apache2::ServerUtil::restart_count, 2, "restart count";
+
+ Apache2::Const::OK;
+}
+
+
+# 11 sub-tests
+sub server_root_relative_tests {
+ my $r = shift;
+
+ my %pools = (
+ '$r->pool' =>
+ $r->pool,
+ '$r->connection->pool' =>
+ $r->connection->pool,
+ '$r->server->process->pool' =>
+ $r->server->process->pool,
+ '$r->server->process->pconf' =>
+ $r->server->process->pconf,
+ 'Apache2::ServerUtil->server->process->pconf' =>
+ Apache2::ServerUtil->server->process->pconf,
+ 'APR::Pool->new' =>
+ APR::Pool->new,
+ );
+
+ # syntax - an object or pool is required
+ t_debug("Apache2::ServerUtil::server_root_relative() died");
+ eval { my $dir = Apache2::ServerUtil::server_root_relative() };
+ t_debug("\$\@: $@");
+ ok $@;
+
+ foreach my $p (keys %pools) {
+ # we will leak memory here when calling the function with a
+ # pool whose life is longer than of $r, but it doesn't matter
+ # for the test
+ ok t_filepath_cmp(
+ canonpath(Apache2::ServerUtil::server_root_relative($pools{$p},
+ 'conf')),
+ catfile($serverroot, 'conf'),
+ "Apache2::ServerUtil:::server_root_relative($p, 'conf')");
+ }
+
+ # syntax - unrecognized objects don't segfault
+ {
+ my $obj = bless {}, 'Apache2::Foo';
+ eval { Apache2::ServerUtil::server_root_relative($obj, 'conf') };
+
+ ok t_cmp($@,
+ qr/p is not of type APR::Pool/,
+ "Apache2::ServerUtil::server_root_relative(\$obj, 'conf')");
+ }
+
+ # no file argument gives ServerRoot
+ {
+ my $server_root_relative =
+ Apache2::ServerUtil::server_root_relative($r->pool);
+
+ ok t_filepath_cmp(canonpath($server_root_relative),
+ canonpath($serverroot),
+ 'server_root_relative($pool)');
+
+ # Apache2::ServerUtil::server_root is also the ServerRoot constant
+ ok t_filepath_cmp(canonpath(Apache2::ServerUtil::server_root),
+ canonpath($server_root_relative),
+ 'Apache2::ServerUtil::server_root');
+
+ }
+
+ {
+ # absolute paths should resolve to themselves
+ my $dir1 = Apache2::ServerUtil::server_root_relative($r->pool, 'logs');
+ my $dir2 = Apache2::ServerUtil::server_root_relative($r->pool, $dir1);
+
+ ok t_filepath_cmp($dir1, $dir2, "absolute path");
+ }
+}
+
+1;
+
+__END__
diff --git a/2_0_13/t/response/TestAPI/show.pm b/2_0_13/t/response/TestAPI/show.pm
new file mode 100644
index 0000000..aece5f0
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/show.pm
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::show;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::MPM ();
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ my $mpm = Apache::Test::config->{server}->{mpm};
+
+ ok t_cmp(Apache2::MPM->show(),
+ qr!$mpm!i,
+ 'Apache2::MPM->show()');
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/slurp_filename.pm b/2_0_13/t/response/TestAPI/slurp_filename.pm
new file mode 100644
index 0000000..27bf236
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/slurp_filename.pm
@@ -0,0 +1,80 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::slurp_filename;
+
+# test slurp_filename()'s taintness options and that it works properly
+# with utf8 data
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestUtil ();
+use ModPerl::Util;
+
+use Apache2::Const -compile => 'OK';
+
+my $expected = <<EOI;
+English: Internet
+Hebrew : \x{05D0}\x{05D9}\x{05E0}\x{05D8}\x{05E8}\x{05E0}\x{05D8}
+EOI
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 5, need 'mod_alias';
+
+ {
+ my $data = $r->slurp_filename(0); # untainted
+ my $received = eval $$data;
+ ok t_cmp($received, $expected, "slurp filename untainted");
+ }
+
+ {
+ my $data = $r->slurp_filename; # tainted
+ my $received = eval { eval $$data };
+ ok t_cmp($@, qr/Insecure dependency in eval/,
+ "slurp filename tainted");
+
+ ModPerl::Util::untaint($$data);
+ $received = eval $$data;
+ ok t_cmp($received, $expected, "slurp filename untainted");
+ }
+
+ {
+ # just in case we will encounter some probs in the future,
+ # here is pure perl function for comparison
+ my $data = slurp_filename_perl($r); # tainted
+ my $received = eval { eval $$data };
+ ok t_cmp($@, qr/Insecure dependency in eval/,
+ "slurp filename (perl) tainted");
+
+ ModPerl::Util::untaint($$data);
+ $received = eval $$data;
+ ok t_cmp($received, $expected, "slurp filename (perl) untainted");
+ }
+
+ Apache2::Const::OK;
+}
+
+sub slurp_filename_perl {
+ my $r = shift;
+ open my $fh, $r->filename;
+ local $/;
+ my $data = <$fh>;
+ close $fh;
+ return \$data;
+}
+
+1;
+__END__
+<NoAutoConfig>
+ <IfModule mod_alias.c>
+ Alias /slurp/ @DocumentRoot@/api/
+ </IfModule>
+ <Location /slurp/>
+ SetHandler modperl
+ PerlResponseHandler TestAPI::slurp_filename
+ </Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/status.pm b/2_0_13/t/response/TestAPI/status.pm
new file mode 100644
index 0000000..b875a09
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/status.pm
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::status;
+
+# see the client for details
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+my $body = "This is a response string";
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my ($code, $string) = split /=/, $r->args || '';
+
+ if ($string) {
+ # status_line must be valid and match status
+ # or it is 'zapped' by httpd as of 2.2.1
+ $r->status($code);
+ $r->status_line("$code $string");
+ }
+ else {
+ $r->status($code);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPI/sub_request.pm b/2_0_13/t/response/TestAPI/sub_request.pm
new file mode 100644
index 0000000..b5b55f0
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/sub_request.pm
@@ -0,0 +1,46 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::sub_request;
+
+# basic subrequest tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK SERVER_ERROR);
+
+my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+sub handler {
+ my $r = shift;
+
+ my $args = $r->args || '';
+ return Apache2::Const::SERVER_ERROR if $args eq 'subreq';
+
+ plan $r, tests => 4;
+
+ my $subr = $r->lookup_uri("$uri?subreq");
+ ok $subr->isa('Apache2::SubRequest');
+
+ ok t_cmp $subr->uri, $uri, "uri";
+
+ my $rc = $subr->run;
+ ok t_cmp $rc, Apache2::Const::SERVER_ERROR, "rc";
+
+ # test an explicit DESTROY (which happens automatically on the
+ # scope exit)
+ undef $subr;
+ ok 1;
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+
diff --git a/2_0_13/t/response/TestAPI/uri.pm b/2_0_13/t/response/TestAPI/uri.pm
new file mode 100644
index 0000000..87ff65d
--- /dev/null
+++ b/2_0_13/t/response/TestAPI/uri.pm
@@ -0,0 +1,188 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPI::uri;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use APR::Pool ();
+use APR::URI ();
+use Apache2::URI ();
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+
+use Apache2::Const -compile => 'OK';
+
+my $location = '/' . Apache::TestRequest::module2path(__PACKAGE__);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 24;
+
+ $r->args('query');
+
+ # basic
+ {
+ my $uri = $r->parsed_uri;
+
+ ok $uri->isa('APR::URI');
+
+ ok t_cmp($uri->path, qr/^$location/, "path");
+
+ my $up = $uri->unparse;
+ ok t_cmp($up, qr/^$location/, "unparse");
+ }
+
+ # construct_server
+ {
+ my $server = $r->construct_server;
+ ok t_cmp(join(':', $r->get_server_name, $r->get_server_port),
+ $server,
+ "construct_server/get_server_name/get_server_port");
+ }
+ {
+ my $hostname = "example.com";
+ my $server = $r->construct_server($hostname);
+ ok t_cmp(join(':', $hostname, $r->get_server_port),
+ $server,
+ "construct_server($hostname)");
+ }
+ {
+ my $hostname = "example.com";
+ my $port = "9097";
+ my $server = $r->construct_server($hostname, $port);
+ ok t_cmp(join(':', $hostname, $port),
+ $server,
+ "construct_server($hostname, $port)");
+
+ }
+ {
+ my $hostname = "example.com";
+ my $port = "9097";
+ my $server = $r->construct_server($hostname, $port, $r->pool->new);
+ ok t_cmp(join(':', $hostname, $port),
+ $server,
+ "construct_server($hostname, $port, new_pool)");
+
+ }
+
+ # construct_url
+ {
+ # if no args are passed then only $r->uri will be included (no
+ # query and no fragment fields)
+ my $curl = $r->construct_url;
+ t_debug("construct_url: $curl");
+ t_debug("r->uri: " . $r->uri);
+ my $parsed = APR::URI->parse($r->pool, $curl);
+
+ ok $parsed->isa('APR::URI');
+
+ my $up = $parsed->unparse;
+ ok t_cmp($up, qr/$location/, "unparse");
+
+ my $path = '/foo/bar';
+
+ $parsed->path($path);
+
+ ok t_cmp($parsed->path, $path, "parsed path");
+ }
+ {
+ # this time include args in the constructed url
+ my $fragment = "fragment";
+ $r->parsed_uri->fragment($fragment);
+ my $curl = $r->construct_url(sprintf "%s?%s", $r->uri, $r->args);
+ t_debug("construct_url: $curl");
+ t_debug("r->uri: ", $r->uri);
+ my $parsed = APR::URI->parse($r->pool, $curl);
+
+ my $up = $parsed->unparse;
+ ok t_cmp($up, qr/$location/, 'construct_url($uri)');
+ ok t_cmp($parsed->query, $r->args, "args vs query");
+ }
+ {
+ # this time include args and a pool object
+ my $curl = $r->construct_url(sprintf("%s?%s", $r->uri, $r->args),
+ $r->pool->new);
+ t_debug("construct_url: $curl");
+ t_debug("r->uri: ", $r->uri);
+ my $up = APR::URI->parse($r->pool, $curl)->unparse;
+ ok t_cmp($up, qr/$location/, 'construct_url($uri, $pool)');
+ }
+
+ # segfault test
+ {
+ # test the segfault in apr < 0.9.2 (fixed on mod_perl side)
+ # passing only the /path
+ my $parsed = APR::URI->parse($r->pool, $r->uri);
+ # set hostname, but not the scheme
+ $parsed->hostname($r->get_server_name);
+ $parsed->port($r->get_server_port);
+ #$parsed->scheme('http');
+ my $expected = $r->construct_url;
+ my $received = $parsed->unparse;
+ t_debug("the real received is: $received");
+ # apr < 0.9.2-dev + fix in mpxs_apr_uri_unparse will return
+ # '://localhost.localdomain:8529/TestAPI::uri'
+ # apr >= 0.9.2 with internal fix will return
+ # '//localhost.localdomain:8529/TestAPI::uri'
+ # so in order to test pre-0.9.2 and post-0.9.2-dev we massage it
+ $expected =~ s|^http:||;
+ $received =~ s|^:||;
+ ok t_cmp($received, $expected,
+ "the bogus url is expected when 'hostname' is set " .
+ "but not 'scheme'");
+ }
+
+ # parse_uri
+ {
+ my $path = "/foo/bar";
+ my $query = "query";
+ my $fragment = "fragment";
+ my $newr = Apache2::RequestRec->new($r->connection, $r->pool);
+ my $url_string = "$path?$query#$fragment";
+
+ # new request
+ $newr->parse_uri($url_string);
+ $newr->path_info('/bar');
+ ok t_cmp($newr->uri, $path, "uri");
+ ok t_cmp($newr->args, $query, "args");
+ ok t_cmp($newr->path_info, '/bar', "path_info");
+
+ my $puri = $newr->parsed_uri;
+ ok t_cmp($puri->path, $path, "path");
+ ok t_cmp($puri->query, $query, "query");
+ ok t_cmp($puri->fragment, $fragment, "fragment");
+
+ #rpath
+ ok t_cmp($puri->rpath, '/foo', "rpath");
+
+ my $port = 6767;
+ $puri->port($port);
+ $puri->scheme('ftp');
+ $puri->hostname('perl.apache.org');
+
+ ok t_cmp($puri->port, $port, "port");
+
+ ok t_cmp($puri->unparse,
+ "ftp://perl.apache.org:$port$path?$query#$fragment",
+ "unparse");
+ }
+
+ # unescape_url
+ {
+ my @c = qw(one two three);
+ my $url_string = join '%20', @c;
+
+ Apache2::URI::unescape_url($url_string);
+
+ ok $url_string eq "@c";
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/base64.pm b/2_0_13/t/response/TestAPR/base64.pm
new file mode 100644
index 0000000..9088fc0
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/base64.pm
@@ -0,0 +1,23 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::base64;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::base64;
+
+sub handler {
+ my $r = shift;
+
+ my $num_of_tests = TestAPRlib::base64::num_of_tests();
+ plan $r, tests => $num_of_tests;
+
+ TestAPRlib::base64::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/brigade.pm b/2_0_13/t/response/TestAPR/brigade.pm
new file mode 100644
index 0000000..167592a
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/brigade.pm
@@ -0,0 +1,107 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::brigade;
+
+# testing APR::Brigade in this tests.
+# Other tests do that too:
+# TestAPR::flatten : flatten()
+# TestAPR::bucket : is_empty(), first(), last()
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use APR::Brigade ();
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::brigade;
+
+sub handler {
+
+ my $r = shift;
+ my $ba = $r->connection->bucket_alloc;
+
+ plan $r, tests => 14 + TestAPRlib::brigade::num_of_tests();
+
+ TestAPRlib::brigade::test();
+
+ # basic + pool + destroy
+ {
+ my $bb = APR::Brigade->new($r->pool, $ba);
+
+ t_debug('$bb is defined');
+ ok defined $bb;
+
+ t_debug('$bb ISA APR::Brigade object');
+ ok $bb->isa('APR::Brigade');
+
+ my $pool = $bb->pool;
+
+ t_debug('$pool is defined');
+ ok defined $pool;
+
+ t_debug('$pool ISA APR::Pool object');
+ ok $pool->isa('APR::Pool');
+
+ t_debug("destroy");
+ $bb->destroy;
+ ok 1;
+ }
+
+ # concat / split / length / flatten
+ {
+ my $bb1 = APR::Brigade->new($r->pool, $ba);
+ $bb1->insert_head(APR::Bucket->new($ba, "11"));
+ $bb1->insert_tail(APR::Bucket->new($ba, "12"));
+
+ my $bb2 = APR::Brigade->new($r->pool, $ba);
+ $bb2->insert_head(APR::Bucket->new($ba, "21"));
+ $bb2->insert_tail(APR::Bucket->new($ba, "22"));
+
+ # concat
+ $bb1->concat($bb2);
+ # bb1: 11, 12, 21, 22
+ ok t_cmp($bb1->length, 8, "total data length in bb");
+ my $len = $bb1->flatten(my $data);
+ ok t_cmp($len, 8, "bb flatten/len");
+ ok t_cmp($data, "11122122", "bb flatten/data");
+ t_debug('$bb2 is empty');
+ ok $bb2->is_empty;
+
+ # split
+ my $b = $bb1->first; # 11
+ $b = $bb1->next($b); # 12
+ my $bb3 = $bb1->split($b);
+
+ # bb1: 11, bb3: 12, 21, 22
+ $len = $bb1->flatten($data);
+ ok t_cmp($len, 2, "bb1 flatten/len");
+ ok t_cmp($data, "11", "bb1 flatten/data");
+ $len = $bb3->flatten($data);
+ ok t_cmp($len, 6, "bb3 flatten/len");
+ ok t_cmp($data, "122122", "bb3 flatten/data");
+ }
+
+ # out-of-scope pools
+ {
+ my $bb1 = APR::Brigade->new(APR::Pool->new, $ba);
+ $bb1->insert_head(APR::Bucket->new($ba, "11"));
+ $bb1->insert_tail(APR::Bucket->new($ba, "12"));
+
+ # try to overwrite the temp pool data
+ require APR::Table;
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+ # now test that we are still OK
+
+ my $len = $bb1->flatten(my $data);
+ ok t_cmp($data, "1112", "correct data");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/bucket.pm b/2_0_13/t/response/TestAPR/bucket.pm
new file mode 100644
index 0000000..6d85abf
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/bucket.pm
@@ -0,0 +1,148 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::bucket;
+
+# a mix of APR::Brigade, APR::Bucket abd APR::BucketType tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use APR::Brigade ();
+use APR::Bucket ();
+use APR::BucketType ();
+use Apache2::Connection ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::bucket;
+
+sub handler {
+
+ my $r = shift;
+
+ plan $r, tests => 20 + TestAPRlib::bucket::num_of_tests();
+
+ TestAPRlib::bucket::test();
+
+ my $ba = $r->connection->bucket_alloc;
+
+ # eos_create / type / length
+ {
+ my $b = APR::Bucket::eos_create($ba);
+ my $type = $b->type;
+ ok t_cmp($type->name, 'EOS', "eos_create");
+
+ ok t_cmp($b->length, 0, "eos b->length");
+
+ # buckets with no data to read should return an empty string
+ my $rlen = $b->read(my $read);
+ ok t_cmp($read, "", 'eos b->read/buffer');
+ ok t_cmp($rlen, 0, 'eos b->read/len');
+ }
+
+ # flush_create
+ {
+ my $b = APR::Bucket::flush_create($ba);
+ my $type = $b->type;
+ ok t_cmp($type->name, 'FLUSH', "flush_create");
+
+ ok t_cmp($b->length, 0, "flush b->length");
+ }
+
+ # insert_after / insert_before / is_eos / is_flush
+ {
+ my $d1 = APR::Bucket->new($ba, "d1");
+ my $d2 = APR::Bucket->new($ba, "d2");
+ my $f1 = APR::Bucket::flush_create($ba);
+ my $f2 = APR::Bucket::flush_create($ba);
+ my $e1 = APR::Bucket::eos_create($ba);
+
+ ### create a chain of buckets
+ my $bb = APR::Brigade->new($r->pool, $ba);
+
+ # head->tail
+ $bb->insert_head( $d1); # head->d1->tail
+ $d1->insert_after( $d2); # head->d1->d2->tail
+ $d2->insert_before($f1); # head->d1->f1->d2->tail
+ $d2->insert_after( $f2); # head->d1->f1->d2->f2->tail
+ $bb->insert_tail( $e1); # head->d1->f1->d2->f2->e1->tail
+
+ ### now test
+ my $b = $bb->first;
+ $b->read(my $read);
+ ok t_cmp($read, "d1", "d1 bucket");
+
+ $b = $bb->next($b);
+ t_debug("is_flush");
+ ok $b->is_flush;
+
+ $b = $bb->next($b);
+ $b->read($read);
+ ok t_cmp($read, "d2", "d2 bucket");
+
+ $b = $bb->last();
+ t_debug("is_eos");
+ ok $b->is_eos;
+
+ $b = $bb->prev($b);
+ t_debug("is_flush");
+ ok $b->is_flush;
+
+ t_debug("not empty");
+ ok !$bb->is_empty;
+
+ # delete all buckets from bb and test that it's empty
+ while (!$bb->is_empty) {
+ my $b = $bb->first;
+ $b->delete;
+ }
+
+ t_debug("empty");
+ ok $bb->is_empty;
+ }
+
+ # check for non-existing buckets first/next/last
+ {
+ my $bb = APR::Brigade->new($r->pool, $ba);
+
+ ok t_cmp($bb->first, undef, "no first bucket");
+ ok t_cmp($bb->last, undef, "no last bucket");
+
+ ## now there is first
+ my $b = APR::Bucket->new($ba, "bbb");
+ $bb->insert_head($b);
+ my $b_first = $bb->first;
+ $b->read(my $read);
+ ok t_cmp($read, "bbb", "first bucket");
+
+ # but there is no prev
+ ok t_cmp($bb->prev($b_first), undef, "no prev bucket");
+
+ # and no next
+ ok t_cmp($bb->next($b_first), undef, "no next bucket");
+ }
+
+ # delete+destroy
+ {
+ my $bb = APR::Brigade->new($r->pool, $ba);
+ $bb->insert_head(APR::Bucket->new($ba, "a"));
+ $bb->insert_head(APR::Bucket->new($ba, "b"));
+
+ my $b1 = $bb->first;
+ $b1->remove;
+ $b1->destroy;
+ ok 1;
+
+ # delete = remove + destroy
+ my $b2 = $bb->first;
+ $b2->delete;
+ ok 1;
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/date.pm b/2_0_13/t/response/TestAPR/date.pm
new file mode 100644
index 0000000..d427fbe
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/date.pm
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::date;
+
+# testing APR::Date API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::date;
+
+sub handler {
+ my $r = shift;
+
+ my $num_of_tests = TestAPRlib::date::num_of_tests();
+ plan $r, tests => $num_of_tests;
+
+ TestAPRlib::date::test();
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestAPR/finfo.pm b/2_0_13/t/response/TestAPR/finfo.pm
new file mode 100644
index 0000000..49cf9df
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/finfo.pm
@@ -0,0 +1,40 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::finfo;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use TestAPRlib::finfo;
+
+use APR::Finfo ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $tests = 1 + TestAPRlib::finfo::num_of_tests();
+ plan $r, tests => $tests;
+
+ {
+ my $finfo = $r->finfo;
+ my $isa = $finfo->isa('APR::Finfo');
+
+ t_debug "\$r->finfo $finfo";
+ ok $isa;
+ }
+
+ # a test assigning to $r->finfo is in TestAPI::request_rec
+
+ TestAPRlib::finfo::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/flatten.pm b/2_0_13/t/response/TestAPR/flatten.pm
new file mode 100644
index 0000000..2246959
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/flatten.pm
@@ -0,0 +1,124 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::flatten;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use TestCommon::Utils;
+
+use Apache2::RequestRec ();
+use APR::Bucket ();
+use APR::Brigade ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+
+ my $r = shift;
+
+ plan $r, tests => 26;
+
+ # first, create a brigade
+ my $pool = $r->pool;
+ my $ba = $r->connection->bucket_alloc;
+
+ my $bb = APR::Brigade->new($pool, $ba);
+
+ # now, let's put several buckets in it
+ for (1 .. 10) {
+ my $data = 'x' x 20000;
+ my $bucket = APR::Bucket->new($ba, $data);
+ $bb->insert_tail($bucket);
+ }
+
+ # ok, that's 10 buckets of 20,000 = 200,000 characters
+ ok t_cmp($bb->length,
+ 200000,
+ 'APR::Brigade::length()');
+
+ # syntax: require a $bb
+ eval { APR::Brigade::flatten("") };
+
+ ok t_cmp($@,
+ qr!usage: \$bb->flatten\(\$buf, \[\$wanted\]\)!,
+ 'APR::Brigade::flatten() requires a brigade');
+
+ # flatten() will slurp up the entire brigade
+ # equivalent to calling apr_brigade_pflatten
+ {
+ my $len = $bb->flatten(my $data);
+
+ verify($len, 200000, $data, 1);
+ }
+
+ # flatten(0) returns 0 bytes
+ {
+ my $len = $bb->flatten(my $data, 0);
+
+ t_debug('$bb->flatten(0) returns a defined value');
+ ok (defined $data);
+
+ verify($len, 0, $data, 0);
+ }
+
+
+ # flatten($length) will return the first $length bytes
+ # equivalent to calling apr_brigade_flatten
+ {
+ # small
+ my $len = $bb->flatten(my $data, 30);
+ verify($len, 30, $data, 1);
+ }
+
+ {
+ # large
+ my $len = $bb->flatten(my $data, 190000);
+ verify($len, 190000, $data, 1);
+ }
+
+ {
+ # more than enough
+ my $len = $bb->flatten(my $data, 300000);
+ verify($len, 200000, $data, 1);
+ }
+
+ # fetch from a brigade with no data in it
+ {
+ my $len = APR::Brigade->new($pool, $ba)->flatten(my $data);
+
+ t_debug('empty brigade returns a defined value');
+ ok (defined $data);
+
+ verify($len, 0, $data, 0);
+ }
+
+ Apache2::Const::OK;
+}
+
+# this sub runs 3 sub-tests with a false $check_content
+# and 4 otherwise
+sub verify {
+ my ($len, $expected_len, $data, $check_content) = @_;
+
+ ok t_cmp($len,
+ $expected_len,
+ "\$bb->flatten(\$data, $len) returned $len bytes");
+ ok t_cmp(length($data),
+ $len,
+ "\$bb->flatten(\$data, $len) returned all expected data");
+
+ ok TestCommon::Utils::is_tainted($data);
+
+ if ($check_content) {
+ # don't use t_cmp() here, else we get 200,000 characters
+ # to look at in verbose mode
+ t_debug("data all 'x' characters");
+ ok ($data !~ m/[^x]/);
+ }
+
+}
+
+
+1;
diff --git a/2_0_13/t/response/TestAPR/ipsubnet.pm b/2_0_13/t/response/TestAPR/ipsubnet.pm
new file mode 100644
index 0000000..1aa3b2e
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/ipsubnet.pm
@@ -0,0 +1,94 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::ipsubnet;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Connection ();
+use Apache2::RequestRec ();
+use APR::Pool ();
+use APR::IpSubnet ();
+use APR::SockAddr ();
+
+use Apache2::Const -compile => 'OK';
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+sub handler {
+ my $r = shift;
+ my $c = $r->connection;
+ my $p = $r->pool;
+
+ plan $r, tests => 8;
+
+ my $ip = APACHE24 ? $c->client_ip : $c->remote_ip;
+
+ ok $ip;
+
+ if (APACHE24) {
+ ok t_cmp($c->client_addr->ip_get, $ip,
+ "client_ip eq client_addr->ip_get");
+ }
+ else {
+ ok t_cmp($c->remote_addr->ip_get, $ip,
+ "remote_ip eq remote_addr->ip_get");
+ }
+
+ {
+ my $ipsub = APR::IpSubnet->new($p, $ip);
+
+ ok $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr);
+ }
+
+ # use IP mask
+ {
+ my $ipsub = APR::IpSubnet->new($p, $ip, "255.0.0.0");
+
+ ok $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr);
+ }
+
+ # fail match
+ {
+ if ($ip =~ /^\d+\.\d+\.\d+\.\d+$/) {
+ # arrange for the subnet to match only one IP, which is
+ # one digit off the client IP, ensuring a mismatch
+ (my $mismatch = $ip) =~ s/(?<=\.)(\d+)$/$1 == 255 ? $1-1 : $1+1/e;
+ t_debug($mismatch);
+ my $ipsub = APR::IpSubnet->new($p, $mismatch, $mismatch);
+ ok ! $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr);
+ }
+ else {
+ # XXX: similar ipv6 trick?
+ ok 1;
+ }
+ }
+
+ # bogus IP
+ {
+ my $ipsub = eval { APR::IpSubnet->new($p, "345.234.678.987") };
+ ok t_cmp($@, qr/The specified IP address is invalid/, "bogus IP");
+ }
+
+ # bogus mask
+ {
+ my $ipsub = eval { APR::IpSubnet->new($p, $ip, "255.0") };
+ ok t_cmp($@, qr/The specified network mask is invalid/, "bogus mask");
+ }
+
+ # temp pool
+ {
+ my $ipsub = APR::IpSubnet->new(APR::Pool->new, $ip);
+ # try to overwrite the temp pool data
+ require APR::Table;
+ my $table = APR::Table::make(APR::Pool->new, 50);
+ $table->set($_ => $_) for 'aa'..'za';
+ # now test that we are still OK
+ ok $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr);
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/os.pm b/2_0_13/t/response/TestAPR/os.pm
new file mode 100644
index 0000000..0ecdafc
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/os.pm
@@ -0,0 +1,31 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::os;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::MPM ();
+use APR::OS ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ if (Apache2::MPM->is_threaded) {
+ my $tid = APR::OS::current_thread_id();
+ ok t_cmp($tid, $tid, "current thread id: $tid / pid: $$");
+ }
+ else {
+ ok t_cmp($$, $$, "current process id");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/perlio.pm b/2_0_13/t/response/TestAPR/perlio.pm
new file mode 100644
index 0000000..d2f4865
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/perlio.pm
@@ -0,0 +1,354 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::perlio;
+
+# to see what happens inside the io layer, assuming that you built
+# mod_perl with MP_TRACE=1, run:
+# env MOD_PERL_TRACE=o t/TEST -v -trace=debug apr/perlio
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Fcntl ();
+use File::Spec::Functions qw(catfile);
+
+use Apache2::Const -compile => qw(OK CRLF);
+
+#XXX: APR::LARGE_FILES_CONFLICT constant?
+#XXX: you can set to zero if largefile support is not enabled in Perl
+use constant LARGE_FILES_CONFLICT => 1;
+
+# apr_file_dup has a bug on win32,
+# should be fixed in apr 0.9.4 / httpd-2.0.48
+require Apache2::Build;
+use constant APR_WIN32_FILE_DUP_BUG =>
+ Apache2::Build::WIN32() && !have_min_apache_version('2.0.48');
+
+sub handler {
+ my $r = shift;
+
+ my $tests = 22;
+ $tests += 3 unless LARGE_FILES_CONFLICT;
+ $tests += 1 unless APR_WIN32_FILE_DUP_BUG;
+
+ require APR::PerlIO;
+ plan $r, tests => $tests,
+ need { "This Perl build doesn't support PerlIO layers" =>
+ APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED() };
+
+ my $vars = Apache::Test::config()->{vars};
+ my $dir = catfile $vars->{documentroot}, "perlio";
+
+ t_mkdir($dir);
+
+ my $sep = "-- sep --\n";
+ my @lines = ("This is a test: $$\n", "test line --sep two\n");
+
+ my $expected = $lines[0];
+ my $expected_all = join $sep, @lines;
+
+ # write file
+ my $file = catfile $dir, "test";
+ t_debug "open file $file for writing";
+ my $foo = "bar";
+ open my $fh, ">:APR", $file, $r->pool
+ or die "Cannot open $file for writing: $!";
+ ok ref($fh) eq 'GLOB';
+
+ t_debug "write to a file:\n$expected\n";
+ print $fh $expected_all;
+ close $fh;
+
+ # open() failure test
+ {
+ # workaround for locale setups where the error message may be
+ # in a different language
+ open my $fh, "perlio_this_file_cannot_exist";
+ my $errno_string = "$!";
+
+ # non-existent file
+ my $file = "/this/file/does/not/exist";
+ if (open my $fh, "<:APR", $file, $r->pool) {
+ t_debug "must not be able to open $file!";
+ ok 0;
+ close $fh;
+ }
+ else {
+ ok t_cmp("$!",
+ $errno_string,
+ "expected failure");
+ }
+ }
+
+ # seek/tell() tests
+ unless (LARGE_FILES_CONFLICT) {
+ open my $fh, "<:APR", $file, $r->pool
+ or die "Cannot open $file for reading: $!";
+
+ # read the whole file so we can test the buffer flushed
+ # correctly on seek.
+ my $dummy = join '', <$fh>;
+
+ # Fcntl::SEEK_SET()
+ my $pos = 3; # rewinds after reading 6 chars above
+ seek $fh, $pos, Fcntl::SEEK_SET();
+ my $got = tell($fh);
+ ok t_cmp($got,
+ $pos,
+ "seek/tell the file Fcntl::SEEK_SET");
+
+ # Fcntl::SEEK_CUR()
+ my $step = 10;
+ $pos = tell($fh) + $step;
+ seek $fh, $step, Fcntl::SEEK_CUR();
+ $got = tell($fh);
+ ok t_cmp($got,
+ $pos,
+ "seek/tell the file Fcntl::SEEK_CUR");
+
+ # Fcntl::SEEK_END()
+ $pos = -s $file;
+ seek $fh, 0, Fcntl::SEEK_END();
+ $got = tell($fh);
+ ok t_cmp($got,
+ $pos,
+ "seek/tell the file Fcntl::SEEK_END");
+
+ close $fh;
+ }
+
+ # read() tests
+ {
+ open my $fh, "<:APR", $file, $r->pool
+ or die "Cannot open $file for reading: $!";
+
+ # basic open test
+ ok ref($fh) eq 'GLOB';
+
+ # basic single line read
+ ok t_cmp(scalar(<$fh>),
+ $expected,
+ "single line read");
+
+ # slurp mode
+ seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start
+ local $/;
+
+ ok t_cmp(scalar(<$fh>),
+ $expected_all,
+ "slurp file");
+
+ # test ungetc (a long sep requires read ahead)
+ seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start
+ local $/ = $sep;
+ my @got_lines = <$fh>;
+ my @expect = ($lines[0] . $sep, $lines[1]);
+ ok t_cmp(\@got_lines,
+ \@expect,
+ "custom complex input record sep read");
+
+ close $fh;
+ }
+
+
+ # eof() tests
+ {
+ open my $fh, "<:APR", $file, $r->pool
+ or die "Cannot open $file for reading: $!";
+
+ ok t_cmp(0,
+ int eof($fh), # returns false, not 0
+ "not end of file");
+ # go to the end and read so eof will return 1
+ seek $fh, 0, Fcntl::SEEK_END();
+ my $received = <$fh>;
+
+ t_debug($received);
+
+ ok t_cmp(eof($fh),
+ 1,
+ "end of file");
+ close $fh;
+ }
+
+ # dup() test
+ {
+ open my $fh, "<:APR", $file, $r->pool
+ or die "Cannot open $file for reading: $!";
+
+ open my $dup_fh, "<&:APR", $fh
+ or die "Cannot dup $file for reading: $!";
+ close $fh;
+ ok ref($dup_fh) eq 'GLOB';
+
+ my $received = <$dup_fh>;
+
+ close $dup_fh;
+ unless (APR_WIN32_FILE_DUP_BUG) {
+ ok t_cmp($received,
+ $expected,
+ "read/write a dupped file");
+ }
+ }
+
+ # unbuffered write
+ {
+ open my $wfh, ">:APR", $file, $r->pool
+ or die "Cannot open $file for writing: $!";
+ open my $rfh, "<:APR", $file, $r->pool
+ or die "Cannot open $file for reading: $!";
+
+ my $expected = "This is an un buffering write test";
+ # unbuffer
+ my $oldfh = select($wfh); $| = 1; select($oldfh);
+ print $wfh $expected; # must be flushed to disk immediately
+
+ ok t_cmp(scalar(<$rfh>),
+ $expected,
+ "file unbuffered write");
+
+ # buffer up
+ $oldfh = select($wfh); $| = 0; select($oldfh);
+ print $wfh $expected; # should be buffered up and not flushed
+
+ ok t_cmp(scalar(<$rfh>),
+ undef,
+ "file buffered write");
+
+ close $wfh;
+ close $rfh;
+
+ }
+
+ # tests reading and writing text and binary files
+ {
+ for my $file ('MoonRise.jpeg', 'redrum.txt') {
+ my $in = catfile $dir, $file;
+ my $out = catfile $dir, "$file.out";
+ my ($apr_content, $perl_content);
+ open my $rfh, "<:APR", $in, $r->pool
+ or die "Cannot open $in for reading: $!";
+ {
+ local $/;
+ $apr_content = <$rfh>;
+ }
+ close $rfh;
+ open my $pfh, "<", $in
+ or die "Cannot open $in for reading: $!";
+ binmode($pfh);
+ {
+ local $/;
+ $perl_content = <$pfh>;
+ }
+ close $pfh;
+ ok t_cmp(length $apr_content,
+ length $perl_content,
+ "testing data size of $file");
+
+ open my $wfh, ">:APR", $out, $r->pool
+ or die "Cannot open $out for writing: $!";
+ print $wfh $apr_content;
+ close $wfh;
+ ok t_cmp(-s $out,
+ -s $in,
+ "testing file size of $file");
+ unlink $out;
+ }
+ }
+
+ # tests for various CRLF and utf-8 issues
+ {
+ my $scratch = catfile $dir, 'scratch.dat';
+ my $text;
+ my $count = 2000;
+ open my $wfh, ">:crlf", $scratch
+ or die "Cannot open $scratch for writing: $!";
+ print $wfh 'a' . ((('a' x 14) . "\n") x $count);
+ close $wfh;
+ open my $rfh, "<:APR", $scratch, $r->pool
+ or die "Cannot open $scratch for reading: $!";
+ {
+ local $/;
+ $text = <$rfh>;
+ }
+ close $rfh;
+ ok t_cmp(count_chars($text, Apache2::Const::CRLF),
+ $count,
+ 'testing for presence of \015\012');
+ ok t_cmp(count_chars($text, "\n"),
+ $count,
+ 'testing for presence of \n');
+
+ open $wfh, ">:APR", $scratch, $r->pool
+ or die "Cannot open $scratch for writing: $!";
+ print $wfh 'a' . ((('a' x 14) . Apache2::Const::CRLF) x $count);
+ close $wfh;
+ open $rfh, "<:APR", $scratch, $r->pool
+ or die "Cannot open $scratch for reading: $!";
+ {
+ local $/;
+ $text = <$rfh>;
+ }
+ close $rfh;
+ ok t_cmp(count_chars($text, Apache2::Const::CRLF),
+ $count,
+ 'testing for presence of \015\012');
+ ok t_cmp(count_chars($text, "\n"),
+ $count,
+ 'testing for presence of \n');
+ open $rfh, "<:crlf", $scratch
+ or die "Cannot open $scratch for reading: $!";
+ {
+ local $/;
+ $text = <$rfh>;
+ }
+ close $rfh;
+ ok t_cmp(count_chars($text, Apache2::Const::CRLF),
+ 0,
+ 'testing for presence of \015\012');
+ ok t_cmp(count_chars($text, "\n"),
+ $count,
+ 'testing for presence of \n');
+
+ my $utf8 = "\x{042F} \x{0432}\x{0430}\x{0441} \x{043B}\x{044E}";
+ open $wfh, ">:APR", $scratch, $r->pool
+ or die "Cannot open $scratch for writing: $!";
+ binmode($wfh, ':utf8');
+ print $wfh $utf8;
+ close $wfh;
+ open $rfh, "<:APR", $scratch, $r->pool
+ or die "Cannot open $scratch for reading: $!";
+ binmode($rfh, ':utf8');
+ {
+ local $/;
+ $text = <$rfh>;
+ }
+ close $rfh;
+ ok t_cmp($text,
+ $utf8,
+ 'utf8 binmode test');
+ unlink $scratch;
+ }
+
+ # XXX: need tests
+ # - for stdin/out/err as they are handled specially
+
+ # XXX: tmpfile is missing:
+ # consider to use 5.8's syntax:
+ # open $fh, "+>", undef;
+
+ # cleanup: t_mkdir will remove the whole tree including the file
+
+ Apache2::Const::OK;
+}
+
+sub count_chars {
+ my ($text, $chars) = @_;
+ my $seen = 0;
+ $seen++ while $text =~ /$chars/g;
+ return $seen;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/pool.pm b/2_0_13/t/response/TestAPR/pool.pm
new file mode 100644
index 0000000..1b04974
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/pool.pm
@@ -0,0 +1,78 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::pool;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::RequestRec ();
+use APR::Pool ();
+use APR::Table ();
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::pool;
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 4 + TestAPRlib::pool::num_of_tests();
+
+ ### native pools ###
+
+ # explicit destroy shouldn't destroy native pools
+ {
+ my $p = $r->pool;
+
+ my $count = TestAPRlib::pool::ancestry_count($p);
+ t_debug "\$r->pool has 2 or more ancestors (found $count)";
+ ok $count >= 2;
+
+ $p->cleanup_register(\&set_cleanup, [$r, 'native destroy']);
+
+ $p->destroy;
+
+ my @notes = $r->notes->get('cleanup');
+
+ ok t_cmp(scalar(@notes), 0, "should be 0 notes");
+
+ $r->notes->clear;
+ }
+
+
+ # implicit DESTROY shouldn't destroy native pools
+ {
+ {
+ my $p = $r->pool;
+
+ my $count = TestAPRlib::pool::ancestry_count($p);
+ t_debug "\$r->pool has 2 or more ancestors (found $count)";
+ ok $count >= 2;
+
+ $p->cleanup_register(\&set_cleanup, [$r, 'native scoped']);
+ }
+
+ my @notes = $r->notes->get('cleanup');
+
+ ok t_cmp(scalar(@notes), 0, "should be 0 notes");
+
+ $r->notes->clear;
+ }
+
+ TestAPRlib::pool::test();
+
+ Apache2::Const::OK;
+}
+
+sub set_cleanup {
+ my $arg = shift;
+ debug "setting cleanup note: $arg->[1]";
+ $arg->[0]->notes->set(cleanup => $arg->[1]);
+ 1;
+}
+
+
+1;
diff --git a/2_0_13/t/response/TestAPR/pool_lifetime.pm b/2_0_13/t/response/TestAPR/pool_lifetime.pm
new file mode 100644
index 0000000..8ac97ac
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/pool_lifetime.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::pool_lifetime;
+
+# this test verifies that if the perl pool object exceeds the
+# life-span of the underlying pool struct we don't get segfaults
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+my $pool;
+
+sub handler {
+ my $r = shift;
+
+ $r->print("Pong");
+ $pool = $r->pool;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/sockaddr.pm b/2_0_13/t/response/TestAPR/sockaddr.pm
new file mode 100644
index 0000000..0b45937
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/sockaddr.pm
@@ -0,0 +1,43 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::sockaddr;
+
+# testing APR::SockAddr API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Connection ();
+use Apache2::RequestRec ();
+use APR::SockAddr ();
+
+use Apache2::Const -compile => 'OK';
+use constant APACHE24 => have_min_apache_version('2.4.0');
+
+sub handler {
+ my $r = shift;
+ my $c = $r->connection;
+
+ plan $r, tests => 4;
+
+ my $local = $c->local_addr;
+ my $remote = APACHE24 ? $c->client_addr : $c->remote_addr;
+
+ ok t_cmp($local->ip_get, $c->local_ip, "local ip");
+ if (APACHE24) {
+ ok t_cmp($remote->ip_get, $c->client_ip, "client ip");
+ }
+ else {
+ ok t_cmp($remote->ip_get, $c->remote_ip, "remote ip");
+ }
+
+ $r->subprocess_env;
+ ok t_cmp($local->port, $ENV{SERVER_PORT}, "local port");
+ ok t_cmp($remote->port, $ENV{REMOTE_PORT}, "remote port");
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/socket.pm b/2_0_13/t/response/TestAPR/socket.pm
new file mode 100644
index 0000000..abbc192
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/socket.pm
@@ -0,0 +1,53 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::socket;
+
+# more tests in t/protocol/TestProtocol/echo_*.pm
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::Connection ();
+use APR::Socket ();
+
+use Apache2::Const -compile => 'OK';
+use APR::Const -compile => 'EMISMATCH';
+
+sub handler {
+ my $r = shift;
+
+ my $tests = 5;
+
+ plan $r, tests => $tests;
+
+ my $c = $r->connection;
+ my $socket = $c->client_socket;
+
+ ok $socket;
+
+ # in microseconds
+ my $orig_val = $socket->timeout_get();
+ t_debug "orig timeout was: $orig_val";
+ ok $orig_val;
+
+ my $new_val = 30_000_000; # 30 secs
+ $socket->timeout_set($new_val);
+ ok t_cmp($socket->timeout_get(), $new_val, "timeout_get()");
+
+ # reset the timeout
+ $socket->timeout_set($orig_val);
+ ok t_cmp($socket->timeout_get(), $orig_val, "timeout_get()");
+
+ skip $^O=~/mswin/i ? 'APR::Socket->fileno is not implemented on MSWin' : '',
+ sub {
+ t_debug "client socket fd=".$socket->fileno;
+ $socket->fileno>0
+ };
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/status.pm b/2_0_13/t/response/TestAPR/status.pm
new file mode 100644
index 0000000..b38b7dd
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/status.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::status;
+
+# Testing APR::Status
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::status;
+
+sub handler {
+ my $r = shift;
+
+ my $num_of_tests = TestAPRlib::status::num_of_tests();
+ plan $r, tests => $num_of_tests;
+
+ TestAPRlib::status::test();
+
+ Apache2::Const::OK;
+}
+
+
+
+1;
diff --git a/2_0_13/t/response/TestAPR/string.pm b/2_0_13/t/response/TestAPR/string.pm
new file mode 100644
index 0000000..61b41f6
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/string.pm
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::string;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+require TestAPRlib::string;
+
+sub handler {
+ my $r = shift;
+
+ my $num_of_tests = TestAPRlib::string::num_of_tests();
+ plan $r, tests => $num_of_tests;
+
+ TestAPRlib::string::test();
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestAPR/table.pm b/2_0_13/t/response/TestAPR/table.pm
new file mode 100644
index 0000000..abe452c
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/table.pm
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::table;
+
+# testing APR::Table API
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::table;
+
+sub handler {
+ my $r = shift;
+
+ my $tests = TestAPRlib::table::num_of_tests();
+ plan $r, tests => $tests;
+
+ TestAPRlib::table::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/threadmutex.pm b/2_0_13/t/response/TestAPR/threadmutex.pm
new file mode 100644
index 0000000..e1df238
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/threadmutex.pm
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::threadmutex;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::threadmutex;
+
+sub handler {
+ my $r = shift;
+
+ my $tests = TestAPRlib::threadmutex::num_of_tests();
+ plan $r, tests => $tests, need_threads;
+
+ TestAPRlib::threadmutex::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/threadrwlock.pm b/2_0_13/t/response/TestAPR/threadrwlock.pm
new file mode 100644
index 0000000..a6ff19f
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/threadrwlock.pm
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::threadrwlock;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::threadrwlock;
+
+sub handler {
+ my $r = shift;
+
+ my $tests = TestAPRlib::threadrwlock::num_of_tests();
+ plan $r, tests => $tests, need_threads;
+
+ TestAPRlib::threadrwlock::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/uri.pm b/2_0_13/t/response/TestAPR/uri.pm
new file mode 100644
index 0000000..89b8471
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/uri.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::uri;
+
+# Testing APR::URI (more tests in TestAPI::uri)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::uri;
+
+sub handler {
+ my $r = shift;
+
+ my $num_of_tests = TestAPRlib::uri::num_of_tests();
+ plan $r, tests => $num_of_tests;
+
+ TestAPRlib::uri::test();
+
+ Apache2::Const::OK;
+}
+
+
+
+1;
diff --git a/2_0_13/t/response/TestAPR/util.pm b/2_0_13/t/response/TestAPR/util.pm
new file mode 100644
index 0000000..19ccfc7
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/util.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::util;
+
+# test APR::Util
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+use TestAPRlib::util;
+
+sub handler {
+ my $r = shift;
+
+ my $num_of_tests = TestAPRlib::util::num_of_tests();
+ plan $r, tests => $num_of_tests;
+
+ TestAPRlib::util::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestAPR/uuid.pm b/2_0_13/t/response/TestAPR/uuid.pm
new file mode 100644
index 0000000..97e81f3
--- /dev/null
+++ b/2_0_13/t/response/TestAPR/uuid.pm
@@ -0,0 +1,23 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestAPR::uuid;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use TestAPRlib::uuid;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => TestAPRlib::uuid::num_of_tests();
+
+ TestAPRlib::uuid::test();
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestApache/cgihandler.pm b/2_0_13/t/response/TestApache/cgihandler.pm
new file mode 100644
index 0000000..be4f2cc
--- /dev/null
+++ b/2_0_13/t/response/TestApache/cgihandler.pm
@@ -0,0 +1,46 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::cgihandler;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use APR::Table ();
+
+use Apache2::Const -compile => qw(OK M_POST);
+
+#test the 1.x style perl-script handler
+
+sub handler {
+ my $r = shift;
+
+ $ENV{FOO} = 2;
+
+ if ($r->method_number == Apache2::Const::M_POST) {
+ my $cl = $r->headers_in->get('content-length');
+ my $buff;
+#XXX: working around a bug in ithreads Perl
+#that would cause modules/cgi #3 to fail
+# read STDIN, $buff, $cl;
+ read 'STDIN', $buff, $cl;
+ print $buff;
+ }
+ else {
+ print "1..3\n";
+ print "ok 1\n", "ok ", "$ENV{FOO}\n";
+#XXX: current implementation of tie %ENV to $r->subprocess_env
+# is not threadsafe
+# my $foo = $r->subprocess_env->get('FOO');
+ my $foo = $ENV{FOO};
+ $foo++;
+ print "ok $foo\n";
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlResponseHandler TestApache::cgihandler
+
diff --git a/2_0_13/t/response/TestApache/conftree.pm b/2_0_13/t/response/TestApache/conftree.pm
new file mode 100644
index 0000000..af13a6e
--- /dev/null
+++ b/2_0_13/t/response/TestApache/conftree.pm
@@ -0,0 +1,114 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::conftree;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestConfig ();
+
+use Apache2::Directive ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $cfg = Apache::Test::config();
+
+ my $node_count = node_count();
+
+ plan $r, tests => 8 + (5*$node_count);
+
+ ok $cfg;
+
+ my $vars = $cfg->{vars};
+
+ ok $vars;
+
+ my $tree = Apache2::Directive::conftree();
+
+ ok $tree;
+
+ my $hostname_lookups = $tree->lookup('HostnameLookups');
+
+ ok t_cmp($hostname_lookups, "Off");
+
+ my $documentroot = $tree->lookup('DocumentRoot');
+
+ ok t_cmp(ref($tree->as_hash()), 'HASH', 'as_hash');
+
+ ok t_cmp($documentroot, qq("$vars->{documentroot}"));
+
+ ok t_cmp($tree->lookup("DocumentRoot"), qq("$vars->{documentroot}"));
+
+ #XXX: This test isn't so good, but its quite problematic to try
+ #and _really_ compare $cfg and $tree...
+ {
+ my %vhosts = map {
+ $cfg->{vhosts}{$_}{name} => { %{$cfg->{vhosts}{$_}}, index => $_ }
+ } keys %{$cfg->{vhosts}};
+
+ for my $v (keys %vhosts) {
+ $vhosts{ $vhosts{$v}{index} } = $vhosts{$v};
+ }
+
+ my $vhost_failed;
+ for my $vhost ($tree->lookup("VirtualHost")) {
+ unless (exists $vhosts{$vhost->{'ServerName'}
+ || $vhost->{'PerlProcessConnectionHandler'}}) {
+ $vhost_failed++;
+ }
+ }
+
+ ok !$vhost_failed;
+ }
+
+ traverse_tree ( \&test_node );
+
+ Apache2::Const::OK;
+}
+
+sub test_node {
+ my ($data, $node) = @_;
+ ok $node->directive;
+ #Args can be null for argless directives
+ ok $node->args || 1;
+ #As string can be null for containers
+ ok $node->as_string || 1;
+ ok $node->filename;
+ ok $node->line_num;
+}
+
+sub traverse_tree {
+ my ($sub, $data) = @_;
+ my $node = Apache2::Directive::conftree();
+ while ($node) {
+ $sub->($data, $node);
+ if (my $kid = $node->first_child) {
+ $node = $kid;
+ }
+ elsif (my $next = $node->next) {
+ $node = $next;
+ }
+ else {
+ if (my $parent = $node->parent) {
+ $node = $parent->next;
+ }
+ else {
+ $node = undef;
+ }
+ }
+ }
+ return;
+}
+
+sub node_count {
+ my $node_count = 0;
+
+ traverse_tree( sub { ${$_[0]}++ }, \$node_count );
+
+ return $node_count;
+}
+1;
diff --git a/2_0_13/t/response/TestApache/content_length_header.pm b/2_0_13/t/response/TestApache/content_length_header.pm
new file mode 100644
index 0000000..acdca06
--- /dev/null
+++ b/2_0_13/t/response/TestApache/content_length_header.pm
@@ -0,0 +1,42 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::content_length_header;
+
+# see the client t/apache/content_length_header.t for the comments
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Response ();
+
+use Apache2::Const -compile => 'OK';
+
+my $body = "This is a response string";
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my $args = $r->args || '';
+
+ if ($args =~ /set_content_length/) {
+ $r->set_content_length(length $body);
+ }
+
+ if ($args =~ /send_body/) {
+ $r->print($body);
+ }
+
+ if ($args =~ /head_no_body/) {
+ if ($r->header_only) {
+ # see #2 in the discussion in the client
+ $r->rflush;
+ }
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestApache/daemon.pm b/2_0_13/t/response/TestApache/daemon.pm
new file mode 100644
index 0000000..c0ae342
--- /dev/null
+++ b/2_0_13/t/response/TestApache/daemon.pm
@@ -0,0 +1,40 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::daemon;
+
+# Apache2::ServerUtil tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::ServerUtil ();
+
+use Apache::TestConfig ();
+use Apache::TestUtil;
+use Apache::Test;
+
+use constant WIN32 => Apache::TestConfig::WIN32;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 2;
+
+ my $user_id = Apache2::ServerUtil->user_id;
+ my $user_id_expected = WIN32 ? 0 : $<;
+
+ ok t_cmp $user_id, $user_id_expected, "user id";
+
+ my $group_id = Apache2::ServerUtil->group_id;
+ my ($group_id_expected) = WIN32 ? 0 : ($( =~ /^(\d+)/);
+
+ ok t_cmp $group_id, $group_id_expected, "group id";
+
+ Apache2::Const::OK;
+}
+
+1;
+
+__END__
+
diff --git a/2_0_13/t/response/TestApache/discard_rbody.pm b/2_0_13/t/response/TestApache/discard_rbody.pm
new file mode 100644
index 0000000..27475e1
--- /dev/null
+++ b/2_0_13/t/response/TestApache/discard_rbody.pm
@@ -0,0 +1,58 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::discard_rbody;
+
+# test $r->discard_request_body when the input body wasn't read at
+# all, read partially or completely.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Connection ();
+use Apache2::Filter ();
+use APR::Brigade ();
+use APR::Error ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => qw(OK MODE_READBYTES);
+use APR::Const -compile => qw(SUCCESS BLOCK_READ);
+
+use constant IOBUFSIZE => 8192;
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ my $test = $r->args;
+
+ if ($test eq 'none') {
+ # don't read the request body
+ }
+ elsif ($test eq 'partial') {
+ # read some of request POSTed data (IOBUFSIZE bytes),
+ # but not all of it
+ my $filters = $r->input_filters();
+ my $ba = $r->connection->bucket_alloc;
+ my $bb = APR::Brigade->new($r->pool, $ba);
+ $filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
+ APR::Const::BLOCK_READ, IOBUFSIZE);
+ }
+ elsif ($test eq 'all') {
+ # consume all of the request body
+ my $data = TestCommon::Utils::read_post($r);
+ die "failed to consume all the data" unless length($data) == 100000;
+ }
+
+ # now get rid of the rest of the input data should work, no matter
+ # how little or how much of the body was read
+ my $rc = $r->discard_request_body;
+ die APR::Error::strerror($rc) unless $rc == Apache2::Const::OK;
+
+ $r->print($test);
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestApache/post.pm b/2_0_13/t/response/TestApache/post.pm
new file mode 100644
index 0000000..40527eb
--- /dev/null
+++ b/2_0_13/t/response/TestApache/post.pm
@@ -0,0 +1,25 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::post;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+ $r->content_type('text/plain');
+
+ my $data = TestCommon::Utils::read_post($r) || "";
+
+ $r->puts(join ':', length($data), $data);
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestApache/read.pm b/2_0_13/t/response/TestApache/read.pm
new file mode 100644
index 0000000..8b90c99
--- /dev/null
+++ b/2_0_13/t/response/TestApache/read.pm
@@ -0,0 +1,47 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::read;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use TestCommon::Utils;
+
+use Apache2::Const -compile => 'OK';
+
+use constant BUFSIZ => 512; #small for testing
+
+sub handler {
+ my $r = shift;
+ $r->content_type('text/plain');
+
+ my $cl = $r->headers_in->get('content-length');
+ my $buffer = "";
+ my $bufsiz = $r->args || BUFSIZ;
+
+ my $offset = 0;
+ while (my $remain = $cl - $offset) {
+ my $len = $remain >= $bufsiz ? $bufsiz : $remain;
+ my $read = $r->read($buffer, $len, $offset);
+ if ($read != $len) {
+ die "read only ${read}b, while ${len}b were requested\n";
+ }
+ last unless $read > 0;
+ $offset += $read;
+ }
+
+ die "read() has returned untainted data:"
+ unless TestCommon::Utils::is_tainted($buffer);
+
+ # make sure we dont block after all data is read
+ my $n = $r->read(my $x, BUFSIZ);
+ die unless $n == 0;
+
+ $r->puts($buffer);
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestApache/read2.pm b/2_0_13/t/response/TestApache/read2.pm
new file mode 100644
index 0000000..4cf7348
--- /dev/null
+++ b/2_0_13/t/response/TestApache/read2.pm
@@ -0,0 +1,42 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::read2;
+
+# extra tests in addition to TestApache::read
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+my $expected = "foobar";
+
+sub handler {
+ my $r = shift;
+
+ # test the case where the buffer to be filled has set magic
+ # attached. which is the case when one passes an non-existing hash
+ # entry value. it's not autovivified when passed to the function
+ # and it's not undef. running SetMAGIC inside read accomplishes
+ # the autovivication in this particular case.
+ my $data;
+ my $len = $r->read($data->{buffer}, $r->headers_in->{'Content-Length'});
+
+ # only print the plan out after reading to avoid chances of a deadlock
+ # see http://mail-archives.apache.org/mod_mbox/perl-dev/201408.mbox/%3C20140809104131.GA3670@estella.local.invalid%3E
+ plan $r, tests => 1;
+
+ ok t_cmp($data->{buffer},
+ $expected,
+ "reading into an autovivified hash entry");
+
+ Apache2::Const::OK;
+}
+1;
+
diff --git a/2_0_13/t/response/TestApache/read3.pm b/2_0_13/t/response/TestApache/read3.pm
new file mode 100644
index 0000000..b1522d5
--- /dev/null
+++ b/2_0_13/t/response/TestApache/read3.pm
@@ -0,0 +1,41 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::read3;
+
+# extra tests in addition to TestApache::read
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+my $expected = "foobar"x2000;
+
+sub handler {
+ my $r = shift;
+
+ # test to read data up to end of file is signaled
+ my $data = '';
+ my $where = 0;
+ my $len;
+ do {
+ $len = $r->read($data, 100, $where);
+ $where += $len;
+ } while ($len > 0);
+
+ # only print the plan out after reading to avoid chances of a deadlock
+ # see http://mail-archives.apache.org/mod_mbox/perl-dev/201408.mbox/%3C20140809104131.GA3670@estella.local.invalid%3E
+ plan $r, tests => 1;
+
+ ok t_cmp($data, $expected, "reading up to end of file");
+
+ Apache2::Const::OK;
+}
+1;
+
diff --git a/2_0_13/t/response/TestApache/read4.pm b/2_0_13/t/response/TestApache/read4.pm
new file mode 100644
index 0000000..2b8f327
--- /dev/null
+++ b/2_0_13/t/response/TestApache/read4.pm
@@ -0,0 +1,116 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::read4;
+
+# extra tests in addition to TestApache::read
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+my @expected = ("123foo",
+ "123456".("\0"x(1000-length("123456")))."bar",
+ "123f",
+ "23f\0\0o",
+ qr/\bread-?only\b/,
+ $^V,
+ "ARo",
+ qr/\bread-?only\b/,
+ ".........",
+ # Reading into $1 (the test above) eats up input since perl
+ # 5.10. This was also the version that blessed $^V as a
+ # "version" object.
+ (ref $^V ? "\0\0ar" : "\0\0bar"),
+ "12",
+ "");
+
+sub X::TIESCALAR {bless []=>'X'}
+sub X::FETCH {$_[0]->[0]}
+sub X::STORE {$_[0]->[0]=$_[1]}
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 12;
+ my $test = 0;
+
+ # we get the string "foobarfoobar" as input here
+
+ # this test consumes 3 bytes
+ my $data = 12345;
+ $r->read($data, 3, -2);
+ ok t_cmp($data, $expected[$test++], "negative offset");
+
+
+ # "barfoobar" still to be read
+ $data = 123456;
+ # now $data is a valid IV but has a PV buffer assigned.
+ # read() has to convert to a valid PV.
+ $r->read($data, 3, 1000);
+ ok t_cmp($data, $expected[$test++], "offset > length of string");
+
+
+ # "foobar" still to be read
+ $r->read($data, 1, 3);
+ ok t_cmp($data, $expected[$test++], "shrink string");
+
+
+ # "oobar" still to be read
+ substr($data, 0, 1) = ''; # set the OOK flag (PV starts at offset 1)
+ $r->read($data, 1, 5);
+ ok t_cmp($data, $expected[$test++], "PV with OOK flag set");
+
+
+ # "obar" still to be read
+ # this test dies BEFORE reading anything
+ eval {$r->read($^V, 1)};
+ ok t_cmp($@, $expected[$test++], "read-only \$^V");
+ ok t_cmp($^V, $expected[$test++], "\$^V untouched");
+
+
+ # "obar" still to be read
+ $data=[];
+ eval {$r->read($data, 1, 2)};
+ ok t_cmp($data, $expected[$test++], "passing an RV as data");
+
+
+ # "bar" still to be read
+ # this test consumes the "b" although it should not
+ "........."=~/(.*)/;
+ eval {$r->read($1, 1)};
+ my $x="$1"; # just in case
+ ok t_cmp($@, $expected[$test++], "read-only \$1");
+ ok t_cmp($x, $expected[$test++], "\$1 untouched");
+
+
+ # "ar" still to be read
+ # now eat up the rest of input
+ tie $data, 'X';
+ $data='';
+ $r->read($data, 100, 2);
+ ok t_cmp(tied($data)->[0], $expected[$test++], "read into a tied buffer");
+
+ untie $data;
+
+
+ # input is empty
+ $data=123456;
+ $r->read($data, 1000, 2);
+ ok t_cmp($data, $expected[$test++], "read at eof");
+
+
+ # input is empty
+ $r->read($data, 1000);
+ ok t_cmp($data, $expected[$test++], "repeated read at eof");
+
+ Apache2::Const::OK;
+}
+1;
+
diff --git a/2_0_13/t/response/TestApache/scanhdrs.pm b/2_0_13/t/response/TestApache/scanhdrs.pm
new file mode 100644
index 0000000..00e3050
--- /dev/null
+++ b/2_0_13/t/response/TestApache/scanhdrs.pm
@@ -0,0 +1,31 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::scanhdrs;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::compat ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ print "Status: 200 Bottles of beer on the wall\n";
+ print 'X-Perl-Module', ': ', __PACKAGE__;
+ print "\r\n";
+ print "Content-type: text/test-";
+ print "output\n";
+ print "\n";
+
+ print "ok 1\n";
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlOptions +ParseHeaders
diff --git a/2_0_13/t/response/TestApache/scanhdrs2.pm b/2_0_13/t/response/TestApache/scanhdrs2.pm
new file mode 100644
index 0000000..7327941
--- /dev/null
+++ b/2_0_13/t/response/TestApache/scanhdrs2.pm
@@ -0,0 +1,24 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::scanhdrs2;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $location = $r->args;
+
+ print "Location: $location\n\n";
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlOptions +ParseHeaders
diff --git a/2_0_13/t/response/TestApache/send_cgi_header.pm b/2_0_13/t/response/TestApache/send_cgi_header.pm
new file mode 100644
index 0000000..9738038
--- /dev/null
+++ b/2_0_13/t/response/TestApache/send_cgi_header.pm
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::send_cgi_header;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Response ();
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ # at the same time test the \0 binary at the beginning of the data
+ my $response = <<EOF;
+Content-type: text/plain
+X-Foo: X-Bar
+Set-Cookie: Bad Programmer, No cookie!
+
+\000\000This not the end of the world\000\000
+EOF
+
+ # bah, we can send the header and the response here
+ # don't tell anybody
+ $r->send_cgi_header($response);
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+# this should work regardless whether parse headers is on or off
+PerlOptions -ParseHeaders
diff --git a/2_0_13/t/response/TestApache/subprocess.pm b/2_0_13/t/response/TestApache/subprocess.pm
new file mode 100644
index 0000000..c6bc3bb
--- /dev/null
+++ b/2_0_13/t/response/TestApache/subprocess.pm
@@ -0,0 +1,180 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::subprocess;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache2::Build;
+
+use File::Spec::Functions qw(catfile catdir);
+use IO::Select ();
+
+use Apache2::Const -compile => 'OK';
+
+use Config;
+
+my $perl = Apache2::Build->build_config()->perl_config('perlpath');
+
+my %scripts = (
+ argv => 'print STDOUT "@ARGV";',
+ env => 'print STDOUT $ENV{SubProcess}',
+ in_out => 'print STDOUT scalar <STDIN>;',
+ in_err => 'print STDERR scalar <STDIN>;',
+ );
+
+sub APACHE_TEST_CONFIGURE {
+ my ($class, $self) = @_;
+
+ my $vars = $self->{vars};
+
+ my $target_dir = catdir $vars->{documentroot}, "util";
+
+ while (my ($file, $code) = each %scripts) {
+ $file = catfile $target_dir, "$file.pl";
+ $self->write_perlscript($file, "$code\n");
+ }
+}
+
+sub handler {
+ my $r = shift;
+
+ my $cfg = Apache::Test::config();
+ my $vars = $cfg->{vars};
+
+ plan $r, tests => 5, need qw(APR::PerlIO Apache2::SubProcess);
+
+ my $target_dir = catfile $vars->{documentroot}, "util";
+
+ {
+ # test: passing argv + void context
+ my $script = catfile $target_dir, "argv.pl";
+ my @argv = qw(foo bar);
+ $r->spawn_proc_prog($perl, [$script, @argv]);
+ # can't really test if something is still returned since it
+ # will be no longer void context
+ ok 1;
+ }
+
+ {
+ # test: passing argv + scalar context
+ my $script = catfile $target_dir, "argv.pl";
+ my @argv = qw(foo bar);
+ my $out_fh = $r->spawn_proc_prog($perl, [$script, @argv]);
+ my $output = read_data($out_fh);
+ ok t_cmp([split / /, $output],
+ \@argv,
+ "passing ARGV"
+ );
+ }
+
+ {
+ # test: passing env to subprocess through subprocess_env
+ my $script = catfile $target_dir, "env.pl";
+ my $value = "my cool proc";
+ $r->subprocess_env->set(SubProcess => $value);
+ my $out_fh = $r->spawn_proc_prog($perl, [$script]);
+ my $output = read_data($out_fh);
+ ok t_cmp($output,
+ $value,
+ "passing env via subprocess_env"
+ );
+ }
+
+ {
+ # test: subproc's stdin -> stdout + list context
+ my $script = catfile $target_dir, "in_out.pl";
+ my $value = "my cool proc\r\n"; # must have \n for <IN>
+ my ($in_fh, $out_fh, $err_fh) =
+ $r->spawn_proc_prog($perl, [$script]);
+ print $in_fh $value;
+ (my $output = read_data($out_fh)) =~ s/[\r\n]{1,2}/\r\n/;
+ ok t_cmp($output,
+ $value,
+ "testing subproc's stdin -> stdout + list context"
+ );
+ }
+
+ {
+ # test: subproc's stdin -> stderr + list context
+ my $script = catfile $target_dir, "in_err.pl";
+ my $value = "my stderr\r\n"; # must have \n for <IN>
+ my ($in_fh, $out_fh, $err_fh) =
+ $r->spawn_proc_prog($perl, [$script]);
+ print $in_fh $value;
+ (my $output = read_data($err_fh)) =~ s/[\r\n]{1,2}/\r\n/;
+ ok t_cmp($output,
+ $value,
+ "testing subproc's stdin -> stderr + list context"
+ );
+ }
+
+# could test send_fd($out), send_fd($err), but currently it's only in
+# compat.pm.
+
+# these are wannabe's
+# ok t_cmp(
+# Apache2::SubProcess::spawn_proc_sub($r, $sub, \@args),
+# Apache2::SUCCESS,
+# "spawn a subprocess and run a subroutine in it"
+# );
+
+# ok t_cmp(
+# Apache2::SubProcess::spawn_thread_prog($r, $command, \@argv),
+# Apache2::SUCCESS,
+# "spawn thread and run a program in it"
+# );
+
+# ok t_cmp(
+# Apache2::SubProcess::spawn_thread_sub($r, $sub, \@args),
+# Apache2::SUCCESS,
+# "spawn thread and run a subroutine in it"
+# );
+
+ Apache2::Const::OK;
+}
+
+
+
+sub read_data {
+ my ($fh) = @_;
+ my @data = ();
+ my $sel = IO::Select->new($fh);
+
+ # here is the catch:
+ #
+ # non-PerlIO pipe fh needs to select if the other end is not fast
+ # enough to send the data, since the read is non-blocking
+ #
+ # PerlIO-based pipe fh on the other hand does the select
+ # internally via apr_wait_for_io_or_timeout() in
+ # apr_file_read() (on *nix, but not on Win32).
+ # But you cannot call select() on the
+ # PerlIO-based, because its fileno() returns (-1), remember that
+ # apr_file_t is an opaque object, and on certain platforms
+ # fileno() is different from unix
+ #
+ # so we use the following wrapper: if we are under perlio we just
+ # go ahead and read the data, but with a short sleep first on Win32;
+ # if we are under non-perlio we first
+ # select for a few secs. (XXX: is 10 secs enough?)
+ #
+ # btw: we use perlIO only for perl 5.7+
+ #
+ if (APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED() || $sel->can_read(10)) {
+ sleep(1) if $^O eq 'MSWin32' && APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED();
+ @data = wantarray ? (<$fh>) : <$fh>;
+ }
+
+ if (wantarray) {
+ return @data;
+ }
+ else {
+ return defined $data[0] ? $data[0] : '';
+ }
+}
+
+1;
+
+
diff --git a/2_0_13/t/response/TestApache/util.pm b/2_0_13/t/response/TestApache/util.pm
new file mode 100644
index 0000000..da61e38
--- /dev/null
+++ b/2_0_13/t/response/TestApache/util.pm
@@ -0,0 +1,128 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::util;
+
+# Apache2::Util tests
+
+use strict;
+use warnings FATAL => 'all';
+
+# to fully test this test the following locale settings need to be run:
+#
+# some /^en_/ locale, e.g. /^en_GB*
+# LC_CTYPE=en_GB.UTF-8 LC_TIME=en_GB.UTF-8 t/TEST -verbose apache/util.t
+# LC_CTYPE=en_GB LC_TIME=en_GB t/TEST -verbose apache/util.t
+#
+# some non-/^en_/ locale, e.g. ru_RU
+# LC_CTYPE=ru_RU.UTF-8 LC_TIME=ru_RU.UTF-8 t/TEST -verbose apache/util.t
+# LC_CTYPE=ru_RU LC_TIME=ru_RU t/TEST -verbose apache/util.t
+
+# regex matching (LC_CTYPE) of strftime-like (LC_TIME) strings
+use locale;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Util ();
+use APR::Date ();
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+# those are passed via PerlPassEnv
+my $locale = $ENV{LC_TIME} || '';
+
+my $parse_time_ok = $locale =~ /^en_/ ? 1 : 0;
+my $locale_is_utf8 = $locale =~ /UTF-8$/ ? 1 : 0;
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 8;
+
+ # ht_time
+ {
+ my $time = time;
+ my $fmt = "%a, %d %b %Y %H:%M:%S %Z";
+ my $fmtdate;
+
+ $fmtdate = Apache2::Util::ht_time($r->pool);
+ time_cmp($fmtdate, $time,
+ 'Apache2::Util::ht_time($pool)', 0);
+
+ $fmtdate = Apache2::Util::ht_time($r->pool, $time);
+ time_cmp($fmtdate, $time,
+ 'Apache2::Util::ht_time($pool, $time)', 1);
+
+ $fmtdate = Apache2::Util::ht_time($r->pool, $time, $fmt);
+ time_cmp($fmtdate, $time,
+ 'Apache2::Util::ht_time($pool, $time, $fmt)', 1);
+
+ my $gmt = 0;
+ $fmtdate = Apache2::Util::ht_time($r->pool, $time, $fmt, $gmt);
+ time_cmp($fmtdate, $time,
+ 'Apache2::Util::ht_time($pool, $time, $fmt, $gmt)', 0);
+ }
+
+ # escape_path
+ {
+ my ($uri, $received, $expected);
+
+ $uri = "a 'long' file?.html";
+ ($expected = $uri) =~ s/([\s?;])/sprintf "%%%x", ord $1/ge;
+
+ $received = Apache2::Util::escape_path($uri, $r->pool);
+ ok t_cmp $received, $expected,
+ "Apache2::Util::escape_path / partial=1 / default";
+
+ $received = Apache2::Util::escape_path($uri, $r->pool, 1);
+ ok t_cmp $received, $expected,
+ "Apache2::Util::escape_path / partial=1 / explicit";
+
+ $received = Apache2::Util::escape_path($uri, $r->pool, 0);
+ ok t_cmp $received, $expected,
+ "Apache2::Util::escape_path / partial=0";
+
+ $uri = "a 'long' file?.html:";
+ ($expected = $uri) =~ s/([\s?;])/sprintf "%%%x", ord $1/ge;
+ # XXX: why does it prepend ./ only if it sees : or :/?
+ $expected = "./$expected";
+
+ $received = Apache2::Util::escape_path($uri, $r->pool, 0);
+ ok t_cmp $received, $expected,
+ "Apache2::Util::escape_path / partial=0 / ./ prefix ";
+
+ }
+
+ Apache2::Const::OK;
+}
+
+my $fmtdate_re = qr/^\w+, \d\d \w+ \d\d\d\d \d\d:\d\d:\d\d/;
+sub time_cmp {
+ my ($fmtdate, $time, $comment, $exact_match) = @_;
+
+ if ($parse_time_ok && $exact_match) {
+ my $ptime = APR::Date::parse_http($fmtdate);
+ t_debug "fmtdate: $fmtdate";
+ ok t_cmp $ptime, $time, $comment;
+ }
+ else {
+ if ($locale_is_utf8) {
+ if (have_min_perl_version(5.008)) {
+ require Encode;
+ # perl doesn't know yet that $fmtdate is a utf8 string
+ $fmtdate = Encode::decode_utf8($fmtdate);
+ }
+ else {
+ skip "Skip locale $locale needs perl 5.8.0+", 0;
+ return;
+ }
+ }
+ ok t_cmp $fmtdate, $fmtdate_re, $comment;
+ }
+}
+
+1;
+
+__END__
+
diff --git a/2_0_13/t/response/TestApache/write.pm b/2_0_13/t/response/TestApache/write.pm
new file mode 100644
index 0000000..ebb7553
--- /dev/null
+++ b/2_0_13/t/response/TestApache/write.pm
@@ -0,0 +1,31 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestApache::write;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+use constant BUFSIZ => 512; #small for testing
+
+sub handler {
+ my $r = shift;
+ $r->content_type('text/plain');
+
+ $r->write("1..2");
+ $r->write("\n", 1);
+
+ my $ok = "ok 1\n";
+ $r->write($ok, 2);
+ $r->write($ok, -1, 2);
+
+ $ok = "not ok 2\n";
+ $r->write($ok, 5, 4);
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestCompat/apache.pm b/2_0_13/t/response/TestCompat/apache.pm
new file mode 100644
index 0000000..9202916
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/apache.pm
@@ -0,0 +1,133 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::apache;
+
+# Apache->"method" and Apache::"function" compat layer tests
+
+# these tests are all run and validated on the server side.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use ModPerl::Util ();
+use Apache2::compat ();
+use Apache::Constants qw(DIR_MAGIC_TYPE OPT_EXECCGI :common :response);
+
+use File::Spec::Functions qw(catfile canonpath);
+
+sub fixup {
+ my $r = shift;
+ Apache->httpd_conf('Options +ExecCGI');
+ OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 24;
+
+ $r->send_http_header('text/plain');
+
+ ### Apache-> tests
+ my $fh = Apache->gensym;
+ ok t_cmp(ref($fh), 'GLOB', "Apache->gensym");
+
+ ok t_cmp(Apache->module('mod_perl.c'), 1,
+ "Apache2::module('mod_perl.c')");
+ ok t_cmp(Apache->module('mod_ne_exists.c'), 0,
+ "Apache2::module('mod_ne_exists.c')");
+
+ ok t_cmp(Apache->define('MODPERL2'),
+ Apache2::ServerUtil::exists_config_define('MODPERL2'),
+ 'Apache->define');
+
+ ok t_cmp($r->current_callback,
+ 'PerlResponseHandler',
+ 'inside PerlResponseHandler');
+
+ t_server_log_error_is_expected();
+ Apache::log_error("Apache::log_error test ok");
+ ok 1;
+
+ t_server_log_warn_is_expected();
+ Apache->warn('Apache->warn ok');
+ ok 1;
+
+ t_server_log_warn_is_expected();
+ Apache::warn('Apache::warn ok');
+ ok 1;
+
+ t_server_log_warn_is_expected();
+ Apache::Server->warn('Apache::Server->warn ok');
+ ok 1;
+
+ t_server_log_warn_is_expected();
+ Apache::Server::warn('Apache::Server::warn ok');
+ ok 1;
+
+ # explicitly imported
+ ok t_cmp(DIR_MAGIC_TYPE, "httpd/unix-directory",
+ 'DIR_MAGIC_TYPE');
+
+ # :response is ignored, but is now aliased in :common
+ ok t_cmp(REDIRECT, "302",
+ 'REDIRECT');
+
+ # from :common
+ ok t_cmp(AUTH_REQUIRED, "401",
+ 'AUTH_REQUIRED');
+
+ ok t_cmp(OK, "0",
+ 'OK');
+
+ my $exec_cgi = $r->allow_options & Apache2::Const::OPT_EXECCGI;
+ ok t_cmp($exec_cgi, Apache2::Const::OPT_EXECCGI, 'Apache->httpd_conf');
+
+ # (Apache||$r)->server_root_relative
+ {
+ my $server_root = Apache::Test::config()->{vars}->{serverroot};
+ ok t_filepath_cmp(canonpath($Apache::Server::CWD),
+ canonpath($server_root),
+ '$server_root');
+
+ ok t_filepath_cmp(canonpath($r->server_root_relative),
+ canonpath($server_root),
+ '$r->server_root_relative()');
+
+ ok t_filepath_cmp(canonpath($r->server_root_relative('conf')),
+ catfile($server_root, 'conf'),
+ "\$r->server_root_relative('conf')");
+
+ ok t_filepath_cmp(canonpath(Apache->server_root_relative('conf')),
+ catfile($server_root, 'conf'),
+ "Apache2::ServerUtil->server_root_relative('conf')");
+
+ ok t_filepath_cmp(canonpath(Apache->server_root_relative),
+ canonpath($server_root),
+ 'Apache2::ServerUtil->server_root_relative()');
+
+ my $path = catfile(Apache2::ServerUtil::server_root, 'logs');
+ ok t_filepath_cmp(canonpath(Apache->server_root_relative($path)),
+ canonpath($path),
+ "Apache->server_root_relative('$path')");
+ }
+
+ ok t_cmp(Apache->unescape_url_info("/foo+bar%20baz"),
+ '/foo bar baz',
+ 'Apache->unescape_url_info');
+
+ ok t_cmp $Apache::Server::Starting, 0, '$Apache::Server::Starting';
+ ok t_cmp $Apache::Server::ReStarting, 1, '$Apache::Server::ReStarting';
+
+ OK;
+}
+
+1;
+
+__END__
+# so we can test whether send_httpd_header() works fine
+PerlOptions +ParseHeaders +GlobalRequest
+PerlModule TestCompat::apache
+PerlFixupHandler TestCompat::apache::fixup
diff --git a/2_0_13/t/response/TestCompat/apache_file.pm b/2_0_13/t/response/TestCompat/apache_file.pm
new file mode 100644
index 0000000..20f0c0c
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/apache_file.pm
@@ -0,0 +1,128 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::apache_file;
+
+# Apache::File compat layer tests
+
+# these tests are all run and validated on the server side.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+use Apache::Constants qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 18;
+
+ $r->send_http_header('text/plain');
+
+ my $cfg = Apache::Test::config();
+ my $vars = $cfg->{vars};
+
+ require Apache::File;
+ my $file = $vars->{t_conf_file};
+
+ t_debug "new Apache2::File file object";
+ ok my $fh = Apache::File->new;
+
+ t_debug "open itself";
+ if ($fh->open($file)) {
+ ok 1;
+ t_debug "read from file";
+ my $read = <$fh>;
+ ok $read;
+ t_debug "close file";
+ ok $fh->close;
+ }
+ else {
+ t_debug "open $file failed: $!";
+ ok 0;
+ t_debug "ok: cannot read from the closed fh";
+ ok 1;
+ t_debug "ok: close file should fail, wasn't opened";
+ ok !$fh->close;
+ }
+
+ t_debug "open non-exists";
+ ok !$fh->open("$file.nochance");
+
+ t_debug "new+open";
+ if (my $fh = Apache::File->new($file)) {
+ ok 1;
+ $fh->close;
+ }
+ else {
+ ok 0;
+ }
+
+ t_debug "new+open non-exists";
+ ok !Apache::File->new("$file.yeahright");
+
+ # tmpfile
+ my ($tmpfile, $tmpfh) = Apache::File->tmpfile;
+
+ t_debug "open tmpfile fh";
+ ok $tmpfh;
+
+ t_debug "open tmpfile name";
+ ok $tmpfile;
+
+ my $write = "test $$";
+ print $tmpfh $write;
+ seek $tmpfh, 0, 0;
+ ok t_cmp(<$tmpfh>, $write, "write/read from tmpfile");
+
+ ok t_cmp($r->discard_request_body,
+ Apache2::Const::OK,
+ "\$r->discard_request_body");
+
+ ok t_cmp($r->meets_conditions,
+ Apache2::Const::OK,
+ "\$r->meets_conditions");
+
+ my $csize = 10;
+ $r->set_content_length($csize);
+ ok t_cmp($r->headers_out->{"Content-length"},
+ $csize,
+ "\$r->set_content_length($csize) w/ setting explicit size");
+
+# #$r->set_content_length();
+# #TODO
+# ok t_cmp(0, # XXX: $r->finfo->csize is not available yet
+# $r->headers_out->{"Content-length"},
+# "\$r->set_content_length() w/o setting explicit size");
+
+
+ # XXX: how to test etag?
+ t_debug "\$r->set_etag";
+ $r->set_etag;
+ ok 1;
+
+ # $r->update_mtime
+ t_debug "\$r->update_mtime()";
+ $r->update_mtime; # just check that it's valid
+ ok 1;
+
+ my $time = time;
+ $r->update_mtime($time);
+ ok t_cmp($r->mtime, $time, "\$r->update_mtime(\$time)/\$r->mtime");
+
+ # $r->set_last_modified
+ $r->set_last_modified();
+ ok t_cmp($r->mtime, $time, "\$r->set_last_modified()");
+
+ $r->set_last_modified($time);
+ ok t_cmp($r->mtime, $time, "\$r->set_last_modified(\$time)");
+
+ OK;
+}
+
+1;
+
+__END__
+PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestCompat/apache_module.pm b/2_0_13/t/response/TestCompat/apache_module.pm
new file mode 100644
index 0000000..2df1df4
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/apache_module.pm
@@ -0,0 +1,51 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::apache_module;
+
+# Apache2::Module compat layer tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+use Apache::Constants qw(OK);
+
+my @directives = (
+ {
+ name => 'TestCompatApacheModuleParms',
+ },
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub TestCompatApacheModuleParms {
+ my ($self, $parms, $args) = @_;
+ my $config = Apache2::Module->get_config($self, $parms->server);
+ $config->{data} = $args;
+}
+
+sub handler : method {
+ my ($self, $r) = @_;
+
+ plan $r, tests => 2;
+
+ my $top_module = Apache2::Module->top_module();
+ ok t_cmp (ref($top_module), 'Apache2::Module');
+
+ my $config = Apache2::Module->get_config($self, $r->server);
+ ok t_cmp ($config->{data}, 'Test');
+
+ OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+PerlLoadModule TestCompat::apache_module
+</Base>
+TestCompatApacheModuleParms "Test"
diff --git a/2_0_13/t/response/TestCompat/apache_table.pm b/2_0_13/t/response/TestCompat/apache_table.pm
new file mode 100644
index 0000000..31d3992
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/apache_table.pm
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::apache_table;
+
+# Apache::Table compat layer tests
+
+# these tests are all run and validated on the server side.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+use Apache::Constants qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 2;
+
+ $r->send_http_header('text/plain');
+
+ my $t = Apache::Table->new($r);
+ my $t_class = ref $t;
+
+ ok t_cmp($t_class, 'APR::Table', "Apache::Table->new");
+
+ ok t_cmp($r->is_main, !$r->main,
+ '$r->is_main');
+
+ OK;
+}
+
+1;
+
diff --git a/2_0_13/t/response/TestCompat/apache_uri.pm b/2_0_13/t/response/TestCompat/apache_uri.pm
new file mode 100644
index 0000000..c830d60
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/apache_uri.pm
@@ -0,0 +1,59 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::apache_uri;
+
+# Apache::Util compat layer tests
+
+# these tests are all run and validated on the server side.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+use Apache::Constants qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 19;
+
+ {
+ # XXX: rpath is not implemented and not in compat
+ my @methods = qw(scheme hostinfo user password hostname path
+ query fragment port);
+ my $test_uri = 'http://foo:bar@perl.apache.org:80/docs?args#frag';
+
+ # Apache2::URI->parse internally returns an object blessed into
+ # APR::URI and all the methods are called on that object
+ for my $uri ($r->parsed_uri, Apache2::URI->parse($r, $test_uri)) {
+ t_debug("URI=" . $uri->unparse);
+ no strict 'refs';
+ # just check that methods are call-able, the actual
+ # testing happens in TestAPR::uri test
+ for my $meth (@methods) {
+ my $val = $uri->$meth();
+ t_debug("$meth: " . ($val||''));
+ ok $val || 1;
+ }
+ }
+ }
+
+ {
+ Apache2::compat::override_mp2_api('APR::URI::unparse');
+ # test the segfault in apr < 0.9.2 (fixed on mod_perl side)
+ # passing only the /path
+ my $parsed = $r->parsed_uri;
+ # set hostname, but not the scheme
+ $parsed->hostname($r->get_server_name);
+ $parsed->port($r->get_server_port);
+ #$parsed->scheme('http'); # compat defaults to 'http' like apache-1.3 did
+ ok t_cmp($parsed->unparse, $r->construct_url);
+ Apache2::compat::restore_mp2_api('APR::URI::unparse');
+ }
+
+ OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestCompat/apache_util.pm b/2_0_13/t/response/TestCompat/apache_util.pm
new file mode 100644
index 0000000..ec1496f
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/apache_util.pm
@@ -0,0 +1,104 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::apache_util;
+
+# Apache::Util compat layer tests
+
+# these tests are all run and validated on the server side.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+use Apache::Constants qw(OK);
+
+my %string_size = (
+ '-1' => " -",
+ 0 => " 0k",
+ 42 => " 1k",
+ 42_000 => " 41k",
+ 42_000_000 => "40.1M",
+ 42_000_000_000 => "40054M",
+);
+
+# list of platforms on which C (not Perl) crypt() is supported
+# XXX: add other platforms that are known to have crypt
+my %crypt_supported = map {$_ => 1} qw(linux);
+
+my $crypt_ok = $crypt_supported{lc $^O} ? 1 : 0;
+
+my $locale = $ENV{LANG} || $ENV{LC_TIME} || '';
+# XXX: will any en_XXX work with http_parse?
+# XXX: should we set $ENV{LANG} to en_US instead of skipping?
+my $parse_time_ok = $locale =~ /^en_/ ? 1 : 0;
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 12 + $parse_time_ok*1 + $crypt_ok*2;
+
+ $r->send_http_header('text/plain');
+
+ # size_string()
+ {
+ while (my ($k, $v) = each %string_size) {
+ ok t_cmp($v, Apache::Util::size_string($k));
+ }
+ }
+
+ # escape_uri(), escape_path(), unescape_uri()
+ my $uri = "http://foo.com/a file.html";
+ (my $esc_uri = $uri) =~ s/ /\%20/g;
+ my $uri2 = $uri;
+
+ $uri = Apache::Util::escape_uri($uri);
+ $uri2 = Apache::Util::escape_path($uri2, $r->pool);
+
+ ok t_cmp($uri, $esc_uri, "Apache::Util::escape_uri");
+ ok t_cmp($uri2, $esc_uri, "Apache::Util::escape_path");
+
+ ok t_cmp(Apache::Util::unescape_uri($uri2),
+ Apache2::URI::unescape_url($uri),
+ "Apache2::URI::unescape_uri vs Apache::Util::unescape_uri");
+
+ ok t_cmp($uri2,
+ $uri,
+ "Apache2::URI::unescape_uri vs Apache::Util::unescape_uri");
+
+ # escape_html()
+ my $html = '<p>"hi"&foo</p>';
+ my $esc_html = '<p>"hi"&foo</p>';
+
+ ok t_cmp(Apache::Util::escape_html($html), $esc_html,
+ "Apache2::Util::escape_html");
+
+
+ # ht_time(), parsedate()
+ my $time = time;
+ Apache2::compat::override_mp2_api('Apache2::Util::ht_time');
+ my $fmtdate = Apache2::Util::ht_time($time);
+ Apache2::compat::restore_mp2_api('Apache2::Util::ht_time');
+
+ ok t_cmp($fmtdate, $fmtdate, "Apache::Util::ht_time");
+
+ if ($parse_time_ok) {
+ my $ptime = Apache::Util::parsedate($fmtdate);
+ ok t_cmp($ptime, $time, "Apache::Util::parsedate");
+ }
+
+ if ($crypt_ok) {
+ # not all platforms support C-level crypt
+ my $hash = "aX9eP53k4DGfU";
+ ok t_cmp(Apache::Util::validate_password("dougm", $hash), 1);
+ ok t_cmp(Apache::Util::validate_password("mguod", $hash), 0);
+ }
+
+ OK;
+}
+
+1;
+
+__END__
+PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestCompat/conn_authen.pm b/2_0_13/t/response/TestCompat/conn_authen.pm
new file mode 100644
index 0000000..1cb80ad
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/conn_authen.pm
@@ -0,0 +1,75 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::conn_authen;
+
+# compat checks for
+# $r->connection->auth_type
+# $r->connection->user
+# both records don't exist in 2.0 conn_rec and therefore require
+# 'PerlOptions +GlobalRequest' to retrieve those via Apache2::RequestUtil->request
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+use Apache::Constants qw(OK REMOTE_HOST);
+
+sub handler {
+
+ my $r = shift;
+
+ my $req_auth_type = $r->connection->auth_type || '';
+
+ die "request auth_type is '$req_auth_type', should be empty"
+ if $req_auth_type;
+
+ # get_basic_auth_pw populates $r->user and $r->ap_auth_type
+ my ($rc, $sent_pw) = $r->get_basic_auth_pw;
+
+ return $rc if $rc != Apache2::Const::OK;
+
+ $req_auth_type = $r->connection->auth_type || '';
+
+ die "request auth_type is '$req_auth_type', should be 'Basic'"
+ unless $req_auth_type eq 'Basic';
+
+ my $config_auth_type = $r->auth_type || '';
+
+ die "httpd.conf auth_type is '$config_auth_type', should be 'Basic'"
+ unless $config_auth_type eq 'Basic';
+
+ my $user = $r->connection->user || '';
+
+ die "user is '$user', should be 'dougm'"
+ unless $user eq 'dougm';
+
+ # make sure we can set both
+ $r->connection->auth_type('sailboat');
+ $r->connection->user('geoff');
+
+ $user = $r->connection->user || '';
+
+ die "user is '$user', should be 'geoff'"
+ unless $user eq 'geoff';
+
+ $req_auth_type = $r->connection->auth_type || '';
+
+ die "request auth_type is '$req_auth_type', should be 'sailboat'"
+ unless $req_auth_type eq 'sailboat';
+
+ OK;
+}
+
+1;
+
+__DATA__
+require valid-user
+AuthType Basic
+AuthName simple
+SetHandler modperl
+PerlOptions +GlobalRequest
+PerlAuthenHandler TestCompat::conn_authen
+PerlResponseHandler Apache::TestHandler::ok1
+
diff --git a/2_0_13/t/response/TestCompat/conn_rec.pm b/2_0_13/t/response/TestCompat/conn_rec.pm
new file mode 100644
index 0000000..a19339c
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/conn_rec.pm
@@ -0,0 +1,42 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::conn_rec;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use Apache2::compat ();
+
+use Socket qw(sockaddr_in inet_ntoa);
+
+use Apache::Constants qw(OK);
+
+sub handler {
+
+ my $r = shift;
+
+ my $c = $r->connection;
+
+ plan $r, tests => 4;
+
+ Apache2::compat::override_mp2_api('Apache2::Connection::local_addr');
+ my ($local_port, $local_addr) = sockaddr_in($c->local_addr);
+ Apache2::compat::restore_mp2_api('Apache2::Connection::local_addr');
+ t_debug inet_ntoa($local_addr) . " :$local_port";
+ ok $local_port;
+ ok inet_ntoa($local_addr);
+
+ Apache2::compat::override_mp2_api('Apache2::Connection::remote_addr');
+ my ($remote_port, $remote_addr) = sockaddr_in($c->remote_addr);
+ Apache2::compat::restore_mp2_api('Apache2::Connection::remote_addr');
+ t_debug inet_ntoa($remote_addr) . " :$remote_port";
+ ok $remote_port;
+ ok inet_ntoa($remote_addr);
+
+ OK;
+}
+
+1;
+
diff --git a/2_0_13/t/response/TestCompat/request.pm b/2_0_13/t/response/TestCompat/request.pm
new file mode 100644
index 0000000..c2406d3
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/request.pm
@@ -0,0 +1,150 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::request;
+
+# $r->"method" compat layer tests
+
+# these tests are all run and validated on the server side.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test;
+
+use APR::Finfo ();
+
+use File::Spec::Functions qw(catfile);
+
+use Apache2::compat ();
+use Apache::Constants qw(OK REMOTE_HOST);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 22;
+
+ $r->send_http_header('text/plain');
+
+ # header_in() and header_out() and err_header_out()
+ for my $prefix ('err_', '') {
+ my @ways = 'out';
+ push @ways, 'in' unless $prefix;
+ for my $way (@ways) {
+ my $sub_test = "${prefix}header_$way";
+ my $sub_good = "${prefix}headers_$way";
+ my $key = 'header-test';
+
+ # scalar context
+ {
+ my $key;
+ if ($way eq 'in') {
+ $key = "user-agent"; # should exist with lwp
+ } else {
+ # outgoing headers aren't set yet, so we set one
+ $key = "X-barabara";
+ $r->$sub_good->set($key, $key x 2);
+ }
+
+ ok t_cmp($r->$sub_test($key),
+ $r->$sub_good->get($key),
+ "\$r->$sub_test in scalar context");
+ }
+
+ # list context
+ {
+ my @exp = qw(foo bar);
+ $r->$sub_good->add($key => $_) for @exp;
+ ok t_cmp([ $r->$sub_test($key) ],
+ \@exp,
+ "\$r->$sub_test in list context");
+ }
+
+ # set
+ {
+ my $exp = $key x 2;
+ $r->$sub_test($key => $exp);
+ my $got = $r->$sub_test($key);
+ ok t_cmp($got, $exp, "\$r->$sub_test set()");
+ }
+
+ # unset
+ {
+ my $exp = undef;
+ $r->$sub_test($key => $exp);
+ my $got = $r->$sub_test($key);
+ ok t_cmp($got, $exp, "\$r->$sub_test unset()");
+ }
+ }
+ }
+
+ # $r->filename
+ {
+ Apache2::compat::override_mp2_api('Apache2::RequestRec::filename');
+ my $orig = $r->filename;
+ my $new = catfile Apache::Test::vars("serverroot"),
+ "conf", "httpd.conf";
+
+ # in mp1 setting filename, updates $r's finfo (not in mp2)
+ $r->filename($new);
+ ok t_cmp $r->finfo->size, -s $new , "new filesize";
+
+ # restore
+ $new = __FILE__;
+ $r->filename($new);
+ ok t_cmp $r->finfo->size, -s $new , "new filesize";
+
+ # restore the real 2.0 filename() method, now that we are done
+ # with the compat one
+ Apache2::compat::restore_mp2_api('Apache2::RequestRec::filename');
+ }
+
+ # $r->notes
+ {
+ Apache2::compat::override_mp2_api('Apache2::RequestRec::notes');
+
+ my $key = 'notes-test';
+ # get/set scalar context
+ {
+ my $val = 'ok';
+ $r->notes($key => $val);
+ ok t_cmp($val, $r->notes->get($key), "\$r->notes->get(\$key)");
+ ok t_cmp($val, $r->notes($key), "\$r->notes(\$key)");
+ }
+
+ # unset
+ {
+ my $exp = undef;
+ $r->notes($key => $exp);
+ my $got = $r->notes($key);
+ ok t_cmp($got, $exp, "\$r->notes unset()");
+ }
+
+ # get/set list context
+ {
+ my @exp = qw(foo bar);
+ $r->notes->add($key => $_) for @exp;
+ ok t_cmp([ $r->notes($key) ], \@exp, "\$r->notes in list context");
+ }
+
+ # restore the real 2.0 notes() method, now that we are done
+ # with the compat one
+ Apache2::compat::restore_mp2_api('Apache2::RequestRec::notes');
+ }
+
+ # get_remote_host()
+ ok $r->get_remote_host() || 1;
+ ok $r->get_remote_host(Apache2::Const::REMOTE_HOST) || 1;
+
+ # post_connection()
+ $r->post_connection(sub { OK });
+ ok 1;
+
+ # register_cleanup
+ ok 1;
+ $r->register_cleanup(sub { OK });
+
+ OK;
+}
+
+1;
+
diff --git a/2_0_13/t/response/TestCompat/request_body.pm b/2_0_13/t/response/TestCompat/request_body.pm
new file mode 100644
index 0000000..5f0f1e9
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/request_body.pm
@@ -0,0 +1,63 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::request_body;
+
+# $r->"method" tests that are validated by the client
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestUtil;
+use Apache::Test ();
+
+use Apache2::compat ();
+use Apache::Constants qw(OK M_POST DECLINED);
+
+use subs qw(ok debug);
+my $gr;
+
+sub handler {
+ my $r = shift;
+ $gr = $r;
+
+ $r->send_http_header('text/plain');
+
+ my $cfg = Apache::Test::config();
+ my $vars = $cfg->{vars};
+
+ my %data;
+ if ($r->method_number == M_POST) {
+ %data = $r->content;
+ }
+ else {
+ %data = $r->Apache::args;
+ }
+
+ return DECLINED unless exists $data{test};
+
+ if ($data{test} eq 'content' || $data{test} eq 'args') {
+ $r->print("test $data{test}");
+ }
+ elsif ($data{test} eq 'decoding') {
+ $r->print(encode($data{body}));
+ }
+ elsif ($data{test} eq 'big_input') {
+ $r->print(length $data{body});
+ }
+ else {
+ # nothing
+ }
+
+ OK;
+}
+
+sub encode {
+ my $val = shift;
+ $val =~ s/(.)/sprintf "%%%02X", ord $1/eg;
+ $val =~ s/\%20/+/g;
+ return $val;
+}
+
+
+1;
+__END__
+PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestCompat/send_fd.pm b/2_0_13/t/response/TestCompat/send_fd.pm
new file mode 100644
index 0000000..7ee2f53
--- /dev/null
+++ b/2_0_13/t/response/TestCompat/send_fd.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestCompat::send_fd;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => ':common';
+
+sub handler {
+ my $r = shift;
+
+ my $file = $r->args || __FILE__;
+
+ open my $fh, $file or return Apache2::Const::NOT_FOUND;
+
+ my $bytes = $r->send_fd($fh);
+
+ return Apache2::Const::SERVER_ERROR unless $bytes == -s $file;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestDirective/cmdparms.pm b/2_0_13/t/response/TestDirective/cmdparms.pm
new file mode 100644
index 0000000..b3070d2
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/cmdparms.pm
@@ -0,0 +1,140 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::cmdparms;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::CmdParms ();
+use Apache2::Directive ();
+use base qw(Apache2::Module);
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(
+ ACCESS_CONF
+ M_GET
+ M_POST
+ M_PUT
+ M_DELETE
+ OK
+ OR_AUTHCFG
+ OR_FILEINFO
+ OR_INDEXES
+ OR_LIMIT
+ OR_OPTIONS
+ RSRC_CONF
+ NOT_IN_LOCATION
+);
+
+use constant KEY => "TestCmdParms";
+
+my @directives = (
+ {
+ name => +KEY,
+ cmd_data => 'cmd_data',
+ errmsg => 'errmsg',
+ },
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+my @methods = qw(cmd context directive info override path
+ pool server temp_pool);
+
+sub TestCmdParms {
+ my ($self, $parms, $args) = @_;
+ my $srv_cfg = $self->get_config($parms->server);
+ foreach my $method (@methods) {
+ $srv_cfg->{$args}{$method} = $parms->$method();
+ }
+ $srv_cfg->{$args}{check_ctx} =
+ $parms->check_cmd_context(Apache2::Const::NOT_IN_LOCATION);
+
+ $srv_cfg->{$args}{limited} = $parms->method_is_limited('GET');
+
+ my $directive = $parms->directive;
+ $srv_cfg->{$args}{line_num} = $directive->line_num;
+ $srv_cfg->{$args}{filename} = $directive->filename;
+}
+
+### response handler ###
+sub handler : method {
+ my ($self, $r) = @_;
+ my $override;
+ my $srv_cfg = $self->get_config($r->server);
+
+ plan $r, tests => 11 + ( 7 * keys(%$srv_cfg) );
+
+ foreach my $cfg (values %$srv_cfg) {
+ ok t_cmp(ref($cfg->{cmd}), 'Apache2::Command', 'cmd');
+ ok t_cmp(ref($cfg->{context}), 'Apache2::ConfVector', 'context');
+ ok t_cmp(ref($cfg->{directive}), 'Apache2::Directive', 'directive');
+ ok t_cmp(ref($cfg->{pool}), 'APR::Pool', 'pool');
+ ok t_cmp(ref($cfg->{temp_pool}), 'APR::Pool', 'temp_pool');
+ ok t_cmp(ref($cfg->{server}), 'Apache2::ServerRec', 'server');
+ ok t_cmp($cfg->{info}, 'cmd_data', 'cmd_data');
+ }
+
+ # vhost
+ {
+ my $vhost = $srv_cfg->{Vhost};
+
+ my $wanted = Apache2::Const::RSRC_CONF |
+ Apache2::Const::OR_INDEXES |
+ Apache2::Const::OR_FILEINFO |
+ Apache2::Const::OR_OPTIONS;
+ my $masked = $vhost->{override} & $wanted;
+
+ ok t_cmp($masked, $wanted, 'override bitmask');
+ ok t_cmp($vhost->{path}, undef, 'path');
+ ok t_cmp($vhost->{check_ctx}, undef, 'check_cmd_ctx');
+ ok $vhost->{limited};
+
+ ok t_cmp $vhost->{filename}, qr|httpd.conf$|, "config filename";
+ ok t_cmp $vhost->{line_num}, qr|^\d+$|, "config filename line_num";
+ }
+
+ # Location
+ {
+ my $loc = $srv_cfg->{Location};
+
+ my $wanted = Apache2::Const::ACCESS_CONF |
+ Apache2::Const::OR_INDEXES |
+ Apache2::Const::OR_AUTHCFG |
+ Apache2::Const::OR_FILEINFO |
+ Apache2::Const::OR_OPTIONS |
+ Apache2::Const::OR_LIMIT;
+ my $masked = $loc->{override} & $wanted;
+
+ ok t_cmp($masked, $wanted, 'override bitmask');
+ ok t_cmp($loc->{path}, '/TestDirective__cmdparms', 'path');
+ ok t_cmp($loc->{check_ctx}, KEY .
+ ' cannot occur within <Location> section', 'check_cmd_ctx');
+ ok $loc->{limited};
+ }
+
+ # Limit
+ {
+ my $limit = $srv_cfg->{Limit};
+ ok !$limit->{limited};
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+PerlLoadModule TestDirective::cmdparms
+TestCmdParms "Vhost"
+</Base>
+
+TestCmdParms "Location"
+#FIXME! httpd 2.4 does not allow LimitExcept here
+#<LimitExcept GET>
+ #TestCmdParms "Limit"
+#</LimitExcept>
diff --git a/2_0_13/t/response/TestDirective/env.pm b/2_0_13/t/response/TestDirective/env.pm
new file mode 100644
index 0000000..8a048ab
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/env.pm
@@ -0,0 +1,101 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::env;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use APR::Table ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 8;
+
+ # %ENV
+ ok t_cmp(env_get('srv1'),
+ 'env_dir1',
+ '%ENV per-dir override per-srv');
+
+ ok t_cmp(env_get('srv2'),
+ 'env_srv2',
+ '%ENV per-srv');
+
+ ok t_cmp(env_get('dir2'),
+ 'env_dir2',
+ '%ENV per-dir');
+
+ # setup by Apache::TestRun
+ ok t_cmp($ENV{APACHE_TEST_HOSTNAME},
+ 'test.host.name',
+ '%ENV PerlPassEnv');
+
+ # $r->subprocess_env
+ ok t_cmp(env_get('srv1', $r),
+ 'env_dir1',
+ '$r->subprocess_env per-dir override per-srv');
+
+ ok t_cmp(env_get('srv2', $r),
+ 'env_srv2',
+ '$r->subprocess_env per-srv');
+
+ ok t_cmp(env_get('dir2', $r),
+ 'env_dir2',
+ '$r->subprocess_env per-dir');
+
+ # setup by Apache::TestRun
+ ok t_cmp($r->subprocess_env->get('APACHE_TEST_HOSTNAME'),
+ 'test.host.name',
+ '$r->subprocess_env PerlPassEnv');
+
+ Apache2::Const::OK;
+}
+
+sub env_get {
+ my ($name, $r) = @_;
+ my $key = 'TestDirective__env_' . $name;
+
+ my $value = $ENV{$key};
+
+ if ($r) {
+ my @values = $r->subprocess_env->get($key);
+
+ if (@values > 1) {
+ $value = "too many values for $key!";
+ }
+ else {
+ $value = $values[0];
+ }
+ }
+
+ return $value;
+}
+
+1;
+__END__
+# SetupEnv ought to have no effect on PerlSetEnv or PerlPassEnv
+PerlOptions -SetupEnv
+
+<Base>
+ # per-server entry overwritten by per-directory entry
+ PerlSetEnv TestDirective__env_srv1 env_srv1
+
+ # per-server entry not overwritten
+ PerlSetEnv TestDirective__env_srv2 env_srv2
+
+ # PerlPassEnv is only per-server
+ PerlPassEnv APACHE_TEST_HOSTNAME
+</Base>
+
+# per-directory entry overwrites per-server
+PerlSetEnv TestDirective__env_srv1 env_dir1
+
+# PerlSetEnv resets the table for each directive
+PerlSetEnv TestDirective__env_dir2 ToBeLost
+PerlSetEnv TestDirective__env_dir2 env_dir2
+
diff --git a/2_0_13/t/response/TestDirective/perlcleanuphandler.pm b/2_0_13/t/response/TestDirective/perlcleanuphandler.pm
new file mode 100644
index 0000000..1908932
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlcleanuphandler.pm
@@ -0,0 +1,66 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlcleanuphandler;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use Apache2::Connection ();
+use Apache2::ConnectionUtil ();
+use Apache2::Const -compile => 'OK', 'DECLINED';
+
+# This test is to show an error that occurs if in the whole request cycle
+# only a PerlCleanupHandler is defined. In this case it is not called.
+# To check that "/get?incr" is called first. This returns "UNDEF" to the
+# browser and sets the counter to "1". Next "/get" is called again without
+# args to check the counter without increment. Then we fetch
+# "/index.html?incr". Here no other Perl*Handler save the PerlCleanupHandler
+# is involved. So the next "/get" must return "2" but it shows "1".
+
+sub cleanup {
+ my $r=shift;
+ $r->connection->pnotes->{counter}++ if( $r->args eq 'incr' );
+ return Apache2::Const::OK;
+}
+
+sub get {
+ my $r=shift;
+ $r->content_type('text/plain');
+ $r->print($r->connection->pnotes->{counter} || "UNDEF");
+ return Apache2::Const::OK;
+}
+
+1;
+
+__END__
+<VirtualHost TestDirective::perlcleanuphandler>
+
+ <IfDefine PERL_USEITHREADS>
+ # a new interpreter pool
+ PerlOptions +Parent
+ PerlInterpStart 1
+ PerlInterpMax 1
+ PerlInterpMinSpare 0
+ PerlInterpMaxSpare 1
+ # PerlInterpScope connection
+ </IfDefine>
+
+ KeepAlive On
+ KeepAliveTimeout 300
+ MaxKeepAliveRequests 100
+
+ # use test system's @INC
+ PerlSwitches -I@serverroot@
+ PerlRequire "conf/modperl_inc.pl"
+ PerlModule TestDirective::perlcleanuphandler
+
+ <Location /get>
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlcleanuphandler::get
+ </Location>
+
+ PerlCleanupHandler TestDirective::perlcleanuphandler::cleanup
+
+</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perldo.pm b/2_0_13/t/response/TestDirective/perldo.pm
new file mode 100644
index 0000000..a825089
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perldo.pm
@@ -0,0 +1,76 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perldo;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache2::Const -compile => 'OK';
+use Apache2::PerlSections;
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 22, need_module('mod_alias');
+
+ ok t_cmp('yes', $TestDirective::perl::worked);
+
+ ok t_cmp($TestDirective::perl::PACKAGE,
+ qr/t::conf::extra_last_conf::line_\d+$/,
+ '__PACKAGE__');
+
+ my %Location;
+ {
+ no strict 'refs';
+ %Location = %{$TestDirective::perl::PACKAGE . '::Location'};
+ }
+
+ ok not exists $Location{'/perl_sections'};
+ ok exists $Location{'/perl_sections_saved'};
+ ok t_cmp($Location{'/perl_sections_saved'}{'AuthName'}, 'PerlSection');
+
+ ok t_cmp($Location{'/tied'}, 'TIED', 'Tied %Location');
+
+ ok t_cmp($TestDirective::perl::comments, 'yes', );
+
+ ok t_cmp($TestDirective::perl::dollar_zero, qr/extra.last.conf/, '$0');
+ ok t_cmp($TestDirective::perl::filename, qr/extra.last.conf/, '__FILE__');
+
+ # 3 would mean we are still counting lines from the context of the eval
+ ok $TestDirective::perl::line > 3;
+
+ ok !t_cmp($0, '-e', '$0');
+ my $target = Apache::Test::vars('target');
+ ok t_cmp($0, qr/$target/i, '$0');
+
+ ok t_cmp($TestDirective::perl::Included, 1, "Include");
+
+ my $dump = Apache2::PerlSections->dump;
+ ok t_cmp($dump, qr/__END__/, "Apache2::PerlSections->dump");
+
+ eval "package TestDirective::perldo::test;\nno strict;\n$dump";
+ ok t_cmp($@, "", "PerlSections dump syntax check");
+
+ ok t_cmp($TestDirective::perldo::test::Include, qr/perlsection.conf/);
+
+ #Check for correct Apache2::ServerUtil->server behavior
+ my $bport = $TestDirective::perl::base_server->port;
+ my $vport = $TestDirective::perl::vhost_server->port;
+ ok defined $bport && defined $vport && $vport != $bport;
+
+ foreach my $url (qw(scalar scalar1 scalar2)) {
+ my $res = GET "/perl_sections_perlconfig_$url/";
+ ok t_cmp($res->is_success, 1, '$PerlConfig');
+ }
+
+ foreach my $url (qw(array1 array2)) {
+ my $res = GET "/perl_sections_perlconfig_$url/";
+ ok t_cmp($res->is_success, 1, '@PerlConfig');
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule.pm b/2_0_13/t/response/TestDirective/perlloadmodule.pm
new file mode 100644
index 0000000..8c85288
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule.pm
@@ -0,0 +1,152 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::Const -compile => qw(OK OR_ALL RSRC_CONF TAKE1 TAKE23);
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+
+my @directives = (
+ {
+ name => 'MyTest',
+ func => __PACKAGE__ . '::MyTest',
+ req_override => Apache2::Const::RSRC_CONF,
+# req_override => 'RSRC_CONF', #test 1.x compat for strings
+# args_how => Apache2::Const::TAKE23,
+ args_how => 'TAKE23', #test 1.x compat for strings
+ errmsg => 'A test',
+ },
+ {
+ name => 'MyOtherTest',
+ cmd_data => 'some info',
+ },
+ {
+ name => 'ServerTest',
+ req_override => Apache2::Const::RSRC_CONF,
+ }
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub DIR_CREATE {
+ my ($class, $parms) = @_;
+
+ bless {
+ path => $parms->path || "/",
+ }, $class;
+}
+
+sub merge {
+ my ($base, $add) = @_;
+
+ my %new = ();
+
+ @new{keys %$base, keys %$add} =
+ (values %$base, values %$add);
+
+ return bless \%new, ref($base);
+}
+
+sub DIR_MERGE {
+ my $class = ref $_[0];
+ debug "$class->DIR_MERGE\n";
+ merge(@_);
+}
+
+#sub SERVER_MERGE {
+# my $class = ref $_[0];
+# debug "$class->SERVER_MERGE\n";
+# merge(@_);
+#}
+
+sub SERVER_CREATE {
+ my ($class, $parms) = @_;
+ debug "$class->SERVER_CREATE\n";
+ return bless {
+ name => __PACKAGE__,
+ }, $class;
+}
+
+sub MyTest {
+ my ($self, $parms, @args) = @_;
+ $self->{MyTest} = \@args;
+ $self->{MyTestInfo} = $parms->info;
+}
+
+sub MyOtherTest {
+ my ($self, $parms, $arg) = @_;
+ $self->{MyOtherTest} = $arg;
+ $self->{MyOtherTestInfo} = $parms->info;
+}
+
+sub ServerTest {
+ my ($self, $parms, $arg) = @_;
+ my $srv_cfg = $self->get_config($parms->server);
+ $srv_cfg->{ServerTest} = $arg;
+}
+
+sub get_config {
+ my ($self, $s) = (shift, shift);
+ Apache2::Module::get_config($self, $s, @_);
+}
+
+sub handler : method {
+ my ($self, $r) = @_;
+
+ my $s = $r->server;
+ my $dir_cfg = $self->get_config($s, $r->per_dir_config);
+ my $srv_cfg = $self->get_config($s);
+
+ plan $r, tests => 9;
+
+ t_debug("per-dir config:", $dir_cfg);
+ t_debug("per-srv config:", $srv_cfg);
+
+ ok $dir_cfg->isa($self);
+ ok $srv_cfg->isa($self);
+
+ my $path = $dir_cfg->{path};
+
+ ok t_cmp($r->uri, qr{^$path},
+ 'r->uri =~ parms->path');
+
+ ok t_cmp($srv_cfg->{name}, $self,
+ '$self eq $srv_cfg->{name}');
+
+ ok t_cmp($dir_cfg->{MyOtherTest}, 'value',
+ 'MyOtherTest value');
+
+ ok t_cmp($dir_cfg->{MyOtherTestInfo}, 'some info',
+ 'MyOtherTest cmd_data');
+
+ ok t_cmp($dir_cfg->{MyTest}, ['one', 'two'],
+ 'MyTest one two');
+
+ ok ! $dir_cfg->{MyTestInfo};
+
+ ok t_cmp($srv_cfg->{ServerTest}, 'per-server');
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+ PerlLoadModule TestDirective::perlloadmodule
+
+ MyTest one two
+ ServerTest per-server
+</Base>
+
+MyOtherTest value
+
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule2.pm b/2_0_13/t/response/TestDirective/perlloadmodule2.pm
new file mode 100644
index 0000000..5829678
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule2.pm
@@ -0,0 +1,114 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule2;
+
+# in this test the merge is inherits all the values from the ancestors
+# and adds new values if such were set
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Const -compile => qw(OK OR_ALL ITERATE);
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+
+my @directives = (
+ {
+ name => 'MyMergeTest',
+ func => __PACKAGE__ . '::MyMergeTest',
+ req_override => Apache2::Const::OR_ALL,
+ args_how => Apache2::Const::ITERATE,
+ errmsg => 'Values that get merged',
+ },
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub merge {
+ my ($base, $add) = @_;
+
+ my %new = ();
+
+ # be careful if the object values are references and not scalars.
+ # If that's the case a deep copy must be performed, or the merged
+ # object will affect the based object, which will break things
+ # when DIR_MERGE is called twice for the same $base/$add during
+ # the same request
+ push @{ $new{$_} }, @{ $base->{$_}||[] } for keys %$base;
+ push @{ $new{$_} }, @{ $add->{$_} ||[] } for keys %$add;
+
+ return bless \%new, ref($base);
+}
+
+sub DIR_MERGE {
+ my $class = ref $_[0];
+ #warn "$class->DIR_MERGE\n";
+ merge(@_);
+}
+
+sub SERVER_MERGE {
+ my $class = ref $_[0];
+ #warn "$class->SERVER_MERGE\n";
+ merge(@_);
+}
+
+# this variable is of type ITERATE, so it'll get called as many times
+# as arguments, a single argument at a time. This function is called
+# only during the server startup and when the directive appears in the
+# .htaccess files
+sub MyMergeTest {
+ my ($self, $parms, $arg) = @_;
+ #warn "MyMergeTest: @{[$parms->path||'']}\n\t$arg\n";
+ push @{ $self->{MyMergeTest} }, $arg;
+
+ # store the top level srv values in the server struct as well, so
+ # during the request you can query what was the top level (srv)
+ # setting, before it was merged with the current container's
+ # setting if any
+ unless ($parms->path) {
+ my $srv_cfg = $self->get_config($parms->server);
+ push @{ $srv_cfg->{MyMergeTest} }, $arg;
+ }
+}
+
+sub get_config {
+ my ($self, $s) = (shift, shift);
+ Apache2::Module::get_config($self, $s, @_);
+}
+
+sub handler : method {
+ my ($self, $r) = @_;
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+
+ if (defined $r->args and $r->args eq 'srv') {
+ my $srv_cfg = $self->get_config($s);
+ $r->print("srv: @{ $srv_cfg->{MyMergeTest}||[] }");
+ }
+ else {
+ my $dir_cfg = $self->get_config($s, $r->per_dir_config);
+ $r->print("dir: @{ $dir_cfg->{MyMergeTest}||[] }");
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+ PerlLoadModule TestDirective::perlloadmodule2
+
+ MyMergeTest one two
+</Base>
+<Location /TestDirective__perlloadmodule2>
+ MyMergeTest three four
+</Location>
+<Location /TestDirective__perlloadmodule2/subdir>
+ MyMergeTest five
+ MyMergeTest six
+</Location>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule3.pm b/2_0_13/t/response/TestDirective/perlloadmodule3.pm
new file mode 100644
index 0000000..facb918
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule3.pm
@@ -0,0 +1,165 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule3;
+
+# in this test we test various merging techniques. As a side effect it
+# tests how mod_perl works when its forced to start early outside
+# vhosts and how it works with vhosts. See perlloadmodule4.pm and
+# perlloadmodule5.pm, for similar tests that starts mod_perl early
+# from a vhost.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+use Apache2::ServerUtil ();
+
+use Apache2::Const -compile => qw(OK);
+
+
+my @directives = (
+ { name => 'MyPlus' },
+ { name => 'MyList' },
+ { name => 'MyAppend' },
+ { name => 'MyOverride' },
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub MyPlus { set_val('MyPlus', @_) }
+sub MyAppend { set_val('MyAppend', @_) }
+sub MyOverride { set_val('MyOverride', @_) }
+sub MyList { push_val('MyList', @_) }
+
+sub DIR_MERGE { merge(@_) }
+sub SERVER_MERGE { merge(@_) }
+
+sub set_val {
+ my ($key, $self, $parms, $arg) = @_;
+ $self->{$key} = $arg;
+ unless ($parms->path) {
+ my $srv_cfg = Apache2::Module::get_config($self, $parms->server);
+ $srv_cfg->{$key} = $arg;
+ }
+}
+
+sub push_val {
+ my ($key, $self, $parms, $arg) = @_;
+ push @{ $self->{$key} }, $arg;
+ unless ($parms->path) {
+ my $srv_cfg = Apache2::Module::get_config($self, $parms->server);
+ push @{ $srv_cfg->{$key} }, $arg;
+ }
+}
+
+sub merge {
+ my ($base, $add) = @_;
+
+ my %mrg = ();
+ for my $key (keys %$base, %$add) {
+ next if exists $mrg{$key};
+ if ($key eq 'MyPlus') {
+ $mrg{$key} = ($base->{$key}||0) + ($add->{$key}||0);
+ }
+ elsif ($key eq 'MyList') {
+ push @{ $mrg{$key} },
+ @{ $base->{$key}||[] }, @{ $add->{$key}||[] };
+ }
+ elsif ($key eq 'MyAppend') {
+ $mrg{$key} = join " ", grep defined, $base->{$key}, $add->{$key};
+ }
+ else {
+ # override mode
+ $mrg{$key} = $base->{$key} if exists $base->{$key};
+ $mrg{$key} = $add->{$key} if exists $add->{$key};
+ }
+ }
+
+ return bless \%mrg, ref($base);
+}
+
+### response handler ###
+
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Module ();
+
+use Apache2::Const -compile => qw(OK);
+
+sub get_config {
+ Apache2::Module::get_config(__PACKAGE__, @_);
+}
+
+sub handler {
+ my ($r) = @_;
+ my %secs = ();
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $dir_cfg = get_config($s, $r->per_dir_config);
+ my $srv_cfg = get_config($s);
+
+ if ($s->is_virtual) {
+ $secs{"1: Main Server"} = get_config(Apache2::ServerUtil->server);
+ $secs{"2: Virtual Host"} = $srv_cfg;
+ $secs{"3: Location"} = $dir_cfg;
+ }
+ else {
+ $secs{"1: Main Server"} = $srv_cfg;
+ $secs{"2: Location"} = $dir_cfg;
+ }
+
+ $r->printf("Processing by %s.\n",
+ $s->is_virtual ? "virtual host" : "main server");
+
+ for my $sec (sort keys %secs) {
+ $r->print("\nSection $sec\n");
+ for my $k (sort keys %{ $secs{$sec}||{} }) {
+ my $v = exists $secs{$sec}->{$k} ? $secs{$sec}->{$k} : 'UNSET';
+ $v = '[' . (join ", ", map {qq{"$_"}} @$v) . ']'
+ if ref($v) eq 'ARRAY';
+ $r->printf("%-10s : %s\n", $k, $v);
+ }
+ }
+
+ return Apache2::Const::OK;
+}
+
+
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+ PerlLoadModule TestDirective::perlloadmodule3
+ MyPlus 5
+ MyList "MainServer"
+ MyAppend "MainServer"
+ MyOverride "MainServer"
+</Base>
+<VirtualHost TestDirective::perlloadmodule3>
+ MyPlus 2
+ MyList "VHost"
+ MyAppend "VHost"
+ MyOverride "VHost"
+ <Location /TestDirective__perlloadmodule3>
+ MyPlus 3
+ MyList "Dir"
+ MyAppend "Dir"
+ MyOverride "Dir"
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlloadmodule3
+ </Location>
+ <Location /TestDirective__perlloadmodule3/subdir>
+ MyPlus 1
+ MyList "SubDir"
+ MyAppend "SubDir"
+ MyOverride "SubDir"
+ </Location>
+</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule4.pm b/2_0_13/t/response/TestDirective/perlloadmodule4.pm
new file mode 100644
index 0000000..6edc88a
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule4.pm
@@ -0,0 +1,98 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule4;
+
+# XXX: the package is 99% the same as perlloadlmodule5 and 6, just the
+# configuration is different. Consider removing the code dups.
+#
+# in this test we test an early mod_perl startup caused by an
+# EXEC_ON_READ directive in the baseserver. In this test the
+# non-native mod_perl directive sets scfg on behalf of mod_perl in
+# that vhost.
+#
+# See also perlloadmodule5.pm, which is almost the same, but uses a
+# mod_perl native directive before a non-native directive in vhost. In
+# that test mod_perl sets scfg for that vhost by itself.
+#
+# see perlloadmodule6.pm for the case where mod_perl starts early, but
+# from within the vhost.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+use Apache2::ServerUtil ();
+
+use Apache2::Const -compile => qw(OK);
+
+use constant KEY => "MyTest4";
+
+my @directives = ({ name => +KEY },);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub MyTest4 {
+ my ($self, $parms, $arg) = @_;
+ $self->{+KEY} = $arg;
+
+ unless ($parms->path) {
+ my $srv_cfg = Apache2::Module::get_config($self, $parms->server);
+ $srv_cfg->{+KEY} = $arg;
+ }
+}
+
+### response handler ###
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Module ();
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+sub get_config {
+ Apache2::Module::get_config(__PACKAGE__, @_);
+}
+
+sub handler {
+ my ($r) = @_;
+ my %secs = ();
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $dir_cfg = get_config($s, $r->per_dir_config);
+ my $srv_cfg = get_config($s);
+
+ plan $r, tests => 3;
+
+ ok $s->is_virtual;
+
+ ok t_cmp($dir_cfg->{+KEY}, "Dir", "Section");
+
+ ok t_cmp($srv_cfg->{+KEY}, "Vhost", "Section");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+ PerlLoadModule TestDirective::perlloadmodule4
+</Base>
+<VirtualHost TestDirective::perlloadmodule4>
+ # here perlloadmodule sets scfg on behalf of the base server
+ MyTest4 "Vhost"
+ <Location /TestDirective__perlloadmodule4>
+ MyTest4 "Dir"
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlloadmodule4
+ </Location>
+</VirtualHost>
+
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule5.pm b/2_0_13/t/response/TestDirective/perlloadmodule5.pm
new file mode 100644
index 0000000..9e88e2c
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule5.pm
@@ -0,0 +1,96 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule5;
+
+# in this test we test an early mod_perl startup caused by an
+# EXEC_ON_READ directive in the baseserver. In this test we have a
+# mod_perl native directive before a non-native directive inside vhost
+# section. Here mod_perl sets scfg for that vhost by itself.
+#
+# See also perlloadmodule4.pm, which is almost the same, but has no
+# mod_perl native directive before a non-native directive in vhost. In
+# that test the non-native mod_perl directive sets scfg on behalf of
+# mod_perl in that vhost.
+#
+# see perlloadmodule6.pm for the case where mod_perl starts early, but
+# from within the vhost.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+use Apache2::ServerUtil ();
+
+use Apache2::Const -compile => qw(OK);
+
+use constant KEY => "MyTest5";
+
+my @directives = ({ name => +KEY },);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub MyTest5 {
+ my ($self, $parms, $arg) = @_;
+ $self->{+KEY} = $arg;
+ unless ($parms->path) {
+ my $srv_cfg = Apache2::Module::get_config($self, $parms->server);
+ $srv_cfg->{+KEY} = $arg;
+ }
+}
+
+### response handler ###
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Module ();
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+sub get_config {
+ Apache2::Module::get_config(__PACKAGE__, @_);
+}
+
+sub handler {
+ my ($r) = @_;
+ my %secs = ();
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $dir_cfg = get_config($s, $r->per_dir_config);
+ my $srv_cfg = get_config($s);
+
+ plan $r, tests => 3;
+
+ ok $s->is_virtual;
+
+ ok t_cmp($dir_cfg->{+KEY}, "Dir", "Section");
+
+ ok t_cmp($srv_cfg->{+KEY}, "Vhost", "Section");
+
+ return Apache2::Const::OK;
+}
+
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+ PerlLoadModule TestDirective::perlloadmodule5
+</Base>
+<VirtualHost TestDirective::perlloadmodule5>
+ # here mod_perl sets the scfg by itself for this vhost
+ PerlModule File::Spec
+ MyTest5 "Vhost"
+ <Location /TestDirective__perlloadmodule5>
+ MyTest5 "Dir"
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlloadmodule5
+ </Location>
+</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule6.pm b/2_0_13/t/response/TestDirective/perlloadmodule6.pm
new file mode 100644
index 0000000..fd8cdfe
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule6.pm
@@ -0,0 +1,90 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule6;
+
+# in this test we test an early mod_perl startup caused by an
+# EXEC_ON_READ directive in vhost.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+use Apache2::ServerUtil ();
+
+use Apache2::Const -compile => qw(OK);
+
+use constant KEY => "MyTest6";
+
+my @directives = ({ name => +KEY },);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub MyTest6 {
+ my ($self, $parms, $arg) = @_;
+ $self->{+KEY} = $arg;
+ unless ($parms->path) {
+ my $srv_cfg = Apache2::Module::get_config($self, $parms->server);
+ $srv_cfg->{+KEY} = $arg;
+ }
+}
+
+### response handler ###
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::Module ();
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+sub get_config {
+ Apache2::Module::get_config(__PACKAGE__, @_);
+}
+
+sub handler {
+ my ($r) = @_;
+ my %secs = ();
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $dir_cfg = get_config($s, $r->per_dir_config);
+ my $srv_cfg = get_config($s);
+
+ plan $r, tests => 3;
+
+ ok $s->is_virtual;
+
+ ok t_cmp($dir_cfg->{+KEY}, "Dir", "Section");
+
+ ok t_cmp($srv_cfg->{+KEY}, "Vhost", "Section");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# XXX: we want to have this configuration section to come first
+# amongst other perlloadmodule tests (<950), so we can test how
+# mod_perl starts from vhost. but currently we can't because
+# PerlSwitches from other tests are ignored, so the test suite fails
+# to startup.
+#
+# tmp solution: ensure that it's configured *after* all other
+# perlloadmodule tests
+#
+# APACHE_TEST_CONFIG_ORDER 951
+
+<VirtualHost TestDirective::perlloadmodule6>
+ PerlLoadModule TestDirective::perlloadmodule6
+ MyTest6 "Vhost"
+ <Location /TestDirective__perlloadmodule6>
+ MyTest6 "Dir"
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlloadmodule6
+ </Location>
+</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule7.pm b/2_0_13/t/response/TestDirective/perlloadmodule7.pm
new file mode 100644
index 0000000..a4fc27a
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlloadmodule7.pm
@@ -0,0 +1,68 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlloadmodule7;
+
+# this test was written to reproduce a segfault under worker
+# due to a bug in custom directive implementation, where
+# the code called from modperl_module_config_merge() was setting the
+# global context after selecting the new interpreter which was leading
+# to a segfault in any handler called thereafter, whose context was
+# different beforehand.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Module ();
+
+use Apache2::Const -compile => qw(OK);
+
+use constant KEY1 => "MyTest7_1";
+use constant KEY2 => "MyTest7_2";
+
+my @directives = ({ name => +KEY1 }, { name => +KEY2 });
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+sub MyTest7_1 {
+ my ($self, $parms, $arg) = @_;
+ $self->{+KEY1} = $arg;
+}
+
+sub MyTest7_2 {
+ my ($self, $parms, $arg) = @_;
+ $self->{+KEY2} = $arg;
+}
+
+### response handler ###
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my ($r) = @_;
+
+ plan $r, tests => 1;
+
+ ok 1;
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+<NoAutoConfig>
+# APACHE_TEST_CONFIG_ORDER 950
+PerlLoadModule TestDirective::perlloadmodule7
+
+MyTest7_1 test
+<Location /TestDirective__perlloadmodule7>
+ MyTest7_2 test
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlloadmodule7
+</Location>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestDirective/perlmodule.pm b/2_0_13/t/response/TestDirective/perlmodule.pm
new file mode 100644
index 0000000..8f926a4
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlmodule.pm
@@ -0,0 +1,62 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlmodule;
+
+# This test is similar to TestDirective::perlrequire. Here we test
+# whether vhost inheriting the parent perl from the base can handle
+# PerlModule directives.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test ();
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use File::Spec::Functions qw(catfile);
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->puts($ApacheTest::PerlModuleTest::MAGIC || '');
+
+ Apache2::Const::OK;
+}
+
+sub APACHE_TEST_CONFIGURE {
+ my ($class, $self) = @_;
+
+ my $vars = $self->{vars};
+ my $target_dir = catfile $vars->{documentroot}, 'testdirective';
+
+ my $magic = __PACKAGE__;
+ my $content = <<EOF;
+package ApacheTest::PerlModuleTest;
+\$ApacheTest::PerlModuleTest::MAGIC = '$magic';
+1;
+EOF
+ my $file = catfile $target_dir,
+ 'perlmodule-vh', 'ApacheTest', 'PerlModuleTest.pm';
+ $self->writefile($file, $content, 1);
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 940
+
+<Base>
+ PerlSwitches -I@documentroot@/testdirective/perlmodule-vh
+</Base>
+
+<VirtualHost TestDirective::perlmodule>
+ PerlModule ApacheTest::PerlModuleTest
+
+ <Location /TestDirective__perlmodule>
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlmodule
+ </Location>
+
+</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlrequire.pm b/2_0_13/t/response/TestDirective/perlrequire.pm
new file mode 100644
index 0000000..1a37130
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/perlrequire.pm
@@ -0,0 +1,88 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::perlrequire;
+
+# Test whether vhost with 'PerlOptions +Parent', which doesn't inherit
+# from the base, has its own INC and therefore can have a modules with
+# the same namespace as the base, but different content.
+#
+# Also see the parallel TestDirective::perlmodule handler
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test ();
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use File::Spec::Functions qw(catfile);
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->puts($ApacheTest::PerlRequireTest::MAGIC || '');
+
+ Apache2::Const::OK;
+}
+
+my %require_tests =
+ (
+ main => 'PerlRequired by Parent',
+ vh => 'PerlRequired by VirtualHost',
+ );
+
+sub APACHE_TEST_CONFIGURE {
+ my ($class, $self) = @_;
+
+ my $vars = $self->{vars};
+ my $target_dir = catfile $vars->{documentroot}, 'testdirective';
+
+ # create two different PerlRequireTest.pm packages to be loaded by
+ # vh and main interpreters, on the fly before the tests start
+ while (my ($test, $magic) = each %require_tests) {
+ my $content = <<EOF;
+package ApacheTest::PerlRequireTest;
+\$ApacheTest::PerlRequireTest::MAGIC = '$magic';
+1;
+EOF
+ my $file = catfile $target_dir,
+ $test, 'ApacheTest', 'PerlRequireTest.pm';
+ $self->writefile($file, $content, 1);
+ }
+}
+
+1;
+__END__
+# APACHE_TEST_CONFIG_ORDER 940
+
+<Base>
+ PerlSwitches -I@documentroot@/testdirective/main
+ PerlRequire "ApacheTest/PerlRequireTest.pm"
+</Base>
+
+<VirtualHost TestDirective::perlrequire>
+
+ <IfDefine PERL_USEITHREADS>
+ # a new interpreter pool
+ PerlOptions +Parent
+ PerlInterpStart 1
+ PerlInterpMax 1
+ PerlInterpMinSpare 1
+ PerlInterpMaxSpare 1
+ </IfDefine>
+
+ # use test system's @INC
+ PerlSwitches -I@serverroot@
+ PerlRequire "conf/modperl_inc.pl"
+
+ PerlSwitches -I@documentroot@/testdirective/vh
+ PerlRequire "ApacheTest/PerlRequireTest.pm"
+
+ <Location /TestDirective__perlrequire>
+ SetHandler modperl
+ PerlResponseHandler TestDirective::perlrequire
+ </Location>
+
+</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/pod.pm b/2_0_13/t/response/TestDirective/pod.pm
new file mode 100644
index 0000000..b220f2b
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/pod.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::pod;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 4;
+
+ ok t_cmp $r->dir_config->get('TestDirective__pod_hidden'), undef;
+ ok t_cmp $r->dir_config->get('TestDirective__pod_over_worked'), 'yes';
+ ok t_cmp $r->dir_config->get('TestDirective__pod_cut_worked'), 'yes';
+
+ #XXX: How to test that __END__ works proprely without cloberring all the other tests?
+ ok t_cmp '__END__', '__END__';
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestDirective/setupenv.pm b/2_0_13/t/response/TestDirective/setupenv.pm
new file mode 100644
index 0000000..dfcdfe7
--- /dev/null
+++ b/2_0_13/t/response/TestDirective/setupenv.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestDirective::setupenv;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $ENV{QS} = $r->args if $r->args;
+
+ while (my ($key, $val) = each %ENV) {
+ next unless $key and $val;
+ $r->puts("$key=$val\n");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+PerlOptions +SetupEnv
+
diff --git a/2_0_13/t/response/TestError/api.pm b/2_0_13/t/response/TestError/api.pm
new file mode 100644
index 0000000..831d99a
--- /dev/null
+++ b/2_0_13/t/response/TestError/api.pm
@@ -0,0 +1,34 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestError::api;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::RequestIO ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ $r->content_type('text/plain');
+
+ # PerlOptions -GlobalRequest is in effect
+ eval { my $gr = Apache2::RequestUtil->request; };
+ ok t_cmp($@,
+ qr/\$r object is not available/,
+ "unavailable global $r object");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+PerlOptions -GlobalRequest
diff --git a/2_0_13/t/response/TestError/runtime.pm b/2_0_13/t/response/TestError/runtime.pm
new file mode 100644
index 0000000..91ca446
--- /dev/null
+++ b/2_0_13/t/response/TestError/runtime.pm
@@ -0,0 +1,162 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestError::runtime;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::Connection ();
+use APR::Socket ();
+use APR::Status ();
+
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+use APR::Const -compile => qw(EACCES);
+
+use constant SIZE => 2048;
+
+sub handler {
+ my $r = shift;
+ my $socket = $r->connection->client_socket;
+ my $args = $r->args;
+
+ $r->content_type('text/plain');
+
+ # set timeout to 0 to make sure that any socket read call will
+ # fail
+ $socket->timeout_set(0);
+
+ no strict 'refs';
+ $args->($r, $socket);
+
+ return Apache2::Const::OK;
+}
+
+sub overload_test {
+ my ($r, $socket) = @_;
+
+ eval { mp_error($socket) };
+
+ die "there should have been an exception" unless $@;
+
+ die "the exception should have been an APR::Error object"
+ unless ref $@ eq 'APR::Error';
+
+ # == && != (expecting an EAGAIN error)
+ die "APR::Status is broken" unless APR::Status::is_EAGAIN($@);
+ die "'==' overload is broken" unless $@ == $@;
+ die "'!=' overload is broken" unless $@ != APR::Const::EACCES;
+ die "'!=' overload is broken" unless APR::Const::EACCES != $@;
+ die "'!=' overload is broken" if $@ != $@;
+
+ # XXX: add more overload tests
+
+ $r->print("ok overload_test");
+
+}
+
+sub plain_mp_error {
+ my ($r, $socket) = @_;
+ t_server_log_error_is_expected();
+ mp_error($socket);
+}
+
+sub plain_non_mp_error {
+ my ($r, $socket) = @_;
+ t_server_log_error_is_expected();
+ non_mp_error($socket);
+}
+
+sub die_hook_confess_mp_error {
+ my ($r, $socket) = @_;
+ local $SIG{__DIE__} = \&APR::Error::confess;
+ t_server_log_error_is_expected();
+ mp_error($socket);
+}
+
+sub die_hook_confess_non_mp_error {
+ my ($r, $socket) = @_;
+ local $SIG{__DIE__} = \&APR::Error::confess;
+ t_server_log_error_is_expected();
+ non_mp_error($socket);
+}
+
+sub die_hook_custom_mp_error {
+ my ($r, $socket) = @_;
+ local $SIG{__DIE__} = sub { die "custom die hook: $_[0]" };
+ t_server_log_error_is_expected();
+ mp_error($socket);
+}
+
+sub die_hook_custom_non_mp_error {
+ my ($r, $socket) = @_;
+ local $SIG{__DIE__} = sub { die "custom die hook: $_[0]" };
+ t_server_log_error_is_expected();
+ non_mp_error($socket);
+}
+
+sub eval_block_mp_error {
+ my ($r, $socket) = @_;
+
+ # throw in some retry attempts
+ my $tries = 0;
+ RETRY: eval { mp_error($socket) };
+ if ($@ && ref($@) && APR::Status::is_EAGAIN($@)) {
+ if ($tries++ < 3) {
+ goto RETRY;
+ }
+ else {
+ $r->print("ok eval_block_mp_error");
+ }
+ }
+ else {
+ die "eval block has failed: $@";
+ }
+}
+
+sub eval_string_mp_error {
+ my ($r, $socket) = @_;
+ eval '$socket->recv(my $buffer, SIZE)';
+ if ($@ && ref($@) && APR::Status::is_EAGAIN($@)) {
+ $r->print("ok eval_string_mp_error");
+ }
+ else {
+ die "eval string has failed: $@";
+ }
+}
+
+sub eval_block_non_mp_error {
+ my ($r, $socket) = @_;
+ eval { non_mp_error($socket) };
+ if ($@ && !ref($@)) {
+ $r->print("ok eval_block_non_mp_error");
+ }
+ else {
+ die "eval eval_non_mp_error has failed: $@";
+ }
+}
+
+sub eval_block_non_error {
+ my ($r, $socket) = @_;
+ eval { 1; };
+ if ($@) {
+ die "eval eval_block_non_mp_error has failed";
+ }
+ $r->print("ok eval_block_non_error");
+}
+
+sub non_mp_error {
+ no_such_func();
+}
+
+# fails because of the timeout set earlier in the handler
+sub mp_error {
+ my $socket = shift;
+ $socket->recv(my $buffer, SIZE);
+}
+
+1;
+__END__
+
diff --git a/2_0_13/t/response/TestError/syntax.pm b/2_0_13/t/response/TestError/syntax.pm
new file mode 100644
index 0000000..3886a8c
--- /dev/null
+++ b/2_0_13/t/response/TestError/syntax.pm
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestError::syntax;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ # the following syntax error is here on purpose!
+ lkj;\;
+
+ $r->print('ok');
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
diff --git a/2_0_13/t/response/TestModperl/cookie.pm b/2_0_13/t/response/TestModperl/cookie.pm
new file mode 100644
index 0000000..32fccf0
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/cookie.pm
@@ -0,0 +1,54 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::cookie;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestTrace;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+sub access {
+ my $r = shift;
+
+ # setup CGI variables early
+ $r->subprocess_env() if $r->args eq 'env';
+
+ my ($key, $val) = cookie($r);
+ my $cookie_is_expected =
+ ($r->args eq 'header' or $r->args eq 'env') ? 1 : 0;
+ die "Can't get the cookie" if $cookie_is_expected && !defined $val;
+
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ my ($key, $val) = cookie($r);
+ $r->print($val) if defined $val;
+
+ return Apache2::Const::OK;
+}
+
+sub cookie {
+ my $r = shift;
+
+ my $header = $r->headers_in->{Cookie} || '';
+ my $env = $ENV{HTTP_COOKIE} || $ENV{COOKIE} || ''; # from CGI::Cookie
+ debug "cookie (" .$r->args . "): header: [$header], env: [$env]";
+
+ return split '=', $r->args eq 'header' ? $header : $env;
+}
+
+1;
+
+__DATA__
+SetHandler perl-script
+PerlModule TestModperl::cookie
+PerlAccessHandler TestModperl::cookie::access
+PerlResponseHandler TestModperl::cookie
+PerlOptions -SetupEnv
diff --git a/2_0_13/t/response/TestModperl/cookie2.pm b/2_0_13/t/response/TestModperl/cookie2.pm
new file mode 100644
index 0000000..1f8a289
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/cookie2.pm
@@ -0,0 +1,49 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::cookie2;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestTrace;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+use Apache2::Const -compile => 'OK';
+
+sub access {
+ my $r = shift;
+
+ $r->subprocess_env if $r->args eq 'subprocess_env';
+ my ($key, $val) = cookie($r);
+ die "I shouldn't get the cookie" if $r->args eq 'env' && defined $val;
+
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ my ($key, $val) = cookie($r);
+ $r->print($val) if defined $val;
+
+ return Apache2::Const::OK;
+}
+
+sub cookie {
+ my $r = shift;
+
+ my $header = $r->headers_in->{Cookie} || '';
+ my $env = $ENV{HTTP_COOKIE} || $ENV{COOKIE} || ''; # from CGI::cookie2
+ debug "cookie (" .$r->args . "): header: [$header], env: [$env]";
+
+ return split '=', $r->args eq 'header' ? $header : $env;
+}
+
+1;
+
+__DATA__
+SetHandler modperl
+PerlModule TestModperl::cookie2
+PerlAccessHandler TestModperl::cookie2::access
+PerlResponseHandler TestModperl::cookie2
diff --git a/2_0_13/t/response/TestModperl/current_callback.pm b/2_0_13/t/response/TestModperl/current_callback.pm
new file mode 100644
index 0000000..a80425f
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/current_callback.pm
@@ -0,0 +1,50 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::current_callback;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use ModPerl::Util;
+
+use APR::Table ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+ my $callback = ModPerl::Util::current_callback();
+ ok t_cmp($callback,
+ 'PerlResponseHandler',
+ 'inside PerlResponseHandler');
+
+ #warn "in callback: $callback\n";
+
+ Apache2::Const::OK;
+}
+
+sub log { check('Log') }
+sub fixup { check('Fixup') }
+sub headerparser { check('HeaderParser') }
+
+sub check {
+ my $expected = 'Perl' . shift() . 'Handler';
+ my $callback = ModPerl::Util::current_callback();
+ die "expecting $expected callback, instead got $callback"
+ unless $callback eq $expected;
+ #warn "in callback: $callback\n";
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlModule TestModperl::current_callback
+PerlHeaderParserHandler TestModperl::current_callback::headerparser
+PerlFixupHandler TestModperl::current_callback::fixup
+PerlResponseHandler TestModperl::current_callback
+PerlLogHandler TestModperl::current_callback::log
+SetHandler modperl
diff --git a/2_0_13/t/response/TestModperl/dir_config.pm b/2_0_13/t/response/TestModperl/dir_config.pm
new file mode 100644
index 0000000..b5608fd
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/dir_config.pm
@@ -0,0 +1,189 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::dir_config;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::RequestUtil ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 15;
+
+ #Apache2::RequestRec::dir_config tests
+
+ # this test doesn't test all $r->dir_config->*(), since
+ # dir_config() returns a generic APR::Table which is tested in
+ # apr/table.t.
+
+ # object test
+ my $dir_config = $r->dir_config;
+ ok defined $dir_config && ref($dir_config) eq 'APR::Table';
+
+ # make sure trying to get something that's not defined
+ # doesn't blow up
+ my $undef = $r->dir_config('EDOESNOTEXIST');
+
+ ok t_cmp($undef, undef,
+ 'no PerlSetVar to get data from');
+
+ # PerlAddVar ITERATE2 test
+ {
+ my $key = make_key('1');
+ my @received = $dir_config->get($key);
+ my @expected = qw(1_SetValue 2_AddValue 3_AddValue 4_AddValue);
+
+ ok t_cmp(\@received, \@expected,
+ 'PerlAddVar ITERATE2');
+ }
+
+ # sub-section inherits from super-section if it doesn't override it
+ {
+ my $key = make_key('_set_in_Base');
+ ok t_cmp($r->dir_config($key),
+ 'BaseValue',
+ "sub-section inherits from super-section " .
+ "if it doesn't override it");
+ }
+
+ # sub-section overrides super-section for the same key
+ {
+ my $key = 'TestModperl__server_rec_Key_set_in_Base';
+ ok t_cmp($r->dir_config->get($key), 'SubSecValue',
+ "sub-section overrides super-section for the same key");
+ }
+
+ {
+ my $key = make_key('0');
+
+ # object interface test in a scalar context (for a single
+ # PerlSetVar key)
+ ok t_cmp($dir_config->get($key),
+ 'SetValue0',
+ "table get() in a scalar context");
+
+ # direct fetch test in a scalar context (for a single
+ # PerlSetVar key)
+ ok t_cmp($r->dir_config($key),
+ 'SetValue0',
+ "direct value fetch in a scalar context");
+ }
+
+ # make sure 0 comes through as 0 and not undef
+ {
+ my $key = 'TestModperl__request_rec_ZeroKey';
+
+ ok t_cmp($r->dir_config($key),
+ 0,
+ 'table value 0 is not undef');
+ }
+
+ # test non-existent key
+ {
+ my $key = make_key();
+
+ ok t_cmp($r->dir_config($key),
+ undef,
+ "non-existent key");
+ }
+
+ # test set interface
+ {
+ my $key = make_key();
+ my $val = "DirConfig";
+
+ $r->dir_config($key => $val);
+
+ ok t_cmp($r->dir_config($key),
+ $val,
+ "set && get");
+ }
+
+ # test unset interface
+ {
+ my $key = make_key();
+
+ $r->dir_config($key => 'whatever');
+ $r->dir_config($key => undef);
+
+ ok t_cmp(undef,
+ $r->dir_config($key),
+ "unset");
+ }
+
+
+ #Apache2::ServerUtil::dir_config tests
+
+ my $s = $r->server;
+
+ # this test doesn't test all $s->dir_config->*(), since
+ # dir_config() returns a generic APR::Table which is tested in
+ # apr/table.t.
+
+ # object test
+ $dir_config = $s->dir_config;
+ ok defined $dir_config && ref($dir_config) eq 'APR::Table';
+
+ # PerlAddVar ITERATE2 test
+ {
+ my $key = 'TestModperl__server_rec_Key_set_in_Base';
+ my @received = $dir_config->get($key);
+ my @expected = qw(1_SetValue 2_AddValue 3_AddValue);
+
+ ok t_cmp(\@received, \@expected,
+ "testing PerlAddVar ITERATE2 in \$s");
+ }
+
+ {
+ # base server test
+ my $bs = Apache2::ServerUtil->server;
+ ok t_cmp(($bs && ref($bs)),
+ 'Apache2::ServerRec',
+ "base server's object retrieval");
+
+ my $key = 'TestModperl__server_rec_Key_set_in_Base';
+ ok t_cmp(scalar ($bs->dir_config->get($key)),
+ '1_SetValue',
+ "read dir_config of the base server");
+ }
+
+ Apache2::Const::OK;
+}
+
+my $key_base = "TestModperl__request_rec_Key";
+my $counter = 0;
+
+sub make_key {
+ return $key_base .
+ (defined $_[0]
+ ? $_[0]
+ : unpack "H*", pack "n", ++$counter . rand(100));
+}
+1;
+__END__
+<Base>
+ PerlSetVar TestModperl__request_rec_Key_set_in_Base BaseValue
+
+ PerlSetVar TestModperl__server_rec_Key_set_in_Base 1_SetValue
+ PerlAddVar TestModperl__server_rec_Key_set_in_Base 2_AddValue 3_AddValue
+</Base>
+
+PerlSetVar TestModperl__request_rec_ZeroKey 0
+
+PerlSetVar TestModperl__request_rec_Key0 SetValue0
+
+PerlSetVar TestModperl__request_rec_Key1 ToBeLost
+PerlSetVar TestModperl__request_rec_Key1 1_SetValue
+PerlAddVar TestModperl__request_rec_Key1 2_AddValue
+PerlAddVar TestModperl__request_rec_Key1 3_AddValue 4_AddValue
+
+PerlSetVar TestModperl__server_rec_Key_set_in_Base SubSecValue
diff --git a/2_0_13/t/response/TestModperl/endav.pm b/2_0_13/t/response/TestModperl/endav.pm
new file mode 100644
index 0000000..5860d52
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/endav.pm
@@ -0,0 +1,59 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::endav;
+
+use strict;
+use warnings FATAL => 'all';
+
+use ModPerl::Global ();
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 4;
+
+ #just to make sure we dont segv with bogus values
+ my $not = 'NoSuchPackage';
+ for my $name ('END', $not) {
+ ModPerl::Global::special_list_call( $name => $not);
+ ModPerl::Global::special_list_clear($name => $not);
+ }
+
+ # register the current package to set its END blocks aside
+ ModPerl::Global::special_list_register(END => __PACKAGE__);
+ # clear anything that was previously set
+ ModPerl::Global::special_list_clear(END => __PACKAGE__);
+ eval 'END { ok 1 }';
+
+ # now run them twice:ok 1 (1), ok 1 (2)
+ ModPerl::Global::special_list_call(END => __PACKAGE__);
+ ModPerl::Global::special_list_call(END => __PACKAGE__);
+
+ ModPerl::Global::special_list_clear(END => __PACKAGE__);
+ #should do nothing
+ ModPerl::Global::special_list_call( END => __PACKAGE__);
+
+ # this we've already registered this package's END blocks, adding
+ # new ones will set them aside
+ eval 'END { ok 1 }';
+
+ # so this will run ok 1 (3)
+ ModPerl::Global::special_list_call( END => __PACKAGE__);
+ ModPerl::Global::special_list_clear(END => __PACKAGE__);
+
+ ModPerl::Global::special_list_clear(END => __PACKAGE__);
+ #should do nothing
+ ModPerl::Global::special_list_call( END => __PACKAGE__);
+
+ # one plain ok 1 (4)
+ ok 1;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/env.pm b/2_0_13/t/response/TestModperl/env.pm
new file mode 100644
index 0000000..ac057a9
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/env.pm
@@ -0,0 +1,87 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::env;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 23 + 3 * keys(%ENV);
+
+ my $env = $r->subprocess_env;
+
+ ok $ENV{MODPERL_EXTRA_PL}; #set in t/conf/modperl_extra.pl
+ ok $ENV{MOD_PERL};
+ ok $ENV{MOD_PERL_API_VERSION};
+
+ ok $ENV{SERVER_SOFTWARE};
+ ok $env->get('SERVER_SOFTWARE');
+
+ {
+ $ENV{FOO} = 2;
+ ok $ENV{FOO} == 2;
+ ok $env->get('FOO') == 2;
+
+ $ENV{FOO}++;
+ ok $ENV{FOO} == 3;
+ ok $env->get('FOO') == 3;
+
+ $ENV{FOO} .= 6;
+ ok $ENV{FOO} == 36;
+ ok $env->get('FOO') == 36;
+
+ delete $ENV{FOO};
+ ok ! $ENV{FOO};
+ ok ! $env->get('FOO');
+ }
+
+ {
+ local %ENV = (FOO => 1, BAR => 2);
+
+ ok $ENV{FOO} == 1;
+ ok $env->get('FOO') == 1;
+
+ ok ! $ENV{SERVER_SOFTWARE};
+ ok ! $env->get('SERVER_SOFTWARE');
+ }
+
+ ok ! $ENV{FOO};
+ skip "r->subprocess_env + local() doesnt fully work yet", 1;
+ #ok ! $env->get('FOO');
+
+ {
+ my $key = 'SERVER_SOFTWARE';
+ my $val = $ENV{SERVER_SOFTWARE};
+ ok $val;
+ ok t_cmp $env->get($key), $val, '$r->subprocess_env->get($key)';
+ ok t_cmp $r->subprocess_env($key), $val, '$r->subprocess_env($key)';
+
+ $val = 'BAR';
+ $r->subprocess_env($key => $val);
+ ok t_cmp $r->subprocess_env($key), $val,
+ '$r->subprocess_env($key => $val)';
+ }
+
+ # make sure each key can be deleted
+ for my $key (sort keys %ENV) {
+ eval { delete $ENV{$key}; };
+ ok t_cmp($@, '', $key);
+ ok t_cmp($ENV{$key}, undef, "ENV{$key} is empty");
+ ok t_cmp($env->get($key), undef, "subprocess_env($key) is empty");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/exit.pm b/2_0_13/t/response/TestModperl/exit.pm
new file mode 100644
index 0000000..31b8e33
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/exit.pm
@@ -0,0 +1,45 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::exit;
+
+# there is no need to call ModPerl::Util::exit() explicitly, a plain
+# exit() will do. We do the explicit fully qualified call in this
+# test, in case something has messed up with CORE::GLOBAL::exit and we
+# want to make sure that we test the right API
+
+use strict;
+use warnings FATAL => 'all';
+
+use ModPerl::Util ();
+
+use Apache2::Const -compile => 'OK';
+use ModPerl::Const -compile => 'EXIT';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ my $args = $r->args;
+
+ if ($args eq 'eval') {
+ eval {
+ my $whatever = 1;
+ ModPerl::Util::exit();
+ };
+ # test whether we can stringify our custom error messages
+ $r->print("$@");
+ ModPerl::Util::exit if $@ && ref $@ && $@ == ModPerl::EXIT;
+ }
+ elsif ($args eq 'noneval') {
+ $r->print("exited");
+ ModPerl::Util::exit();
+ }
+
+ # must not be reached
+ $r->print("must not be reached");
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+
diff --git a/2_0_13/t/response/TestModperl/getc.pm b/2_0_13/t/response/TestModperl/getc.pm
new file mode 100644
index 0000000..1b49f22
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/getc.pm
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::getc;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ untie *STDIN;
+ tie *STDIN, $r;
+
+ while (my $c = getc) {
+ die "got more than 1 char" unless length($c) == 1;
+ $r->puts($c);
+ }
+
+ untie *STDIN;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestModperl/interpreter.pm b/2_0_13/t/response/TestModperl/interpreter.pm
new file mode 100644
index 0000000..0e01f9b
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/interpreter.pm
@@ -0,0 +1,81 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::interpreter;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::MPM ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $is_threaded=Apache2::MPM->is_threaded;
+
+ plan $r, tests => $is_threaded?17:5, need
+ need_threads,
+ {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)};
+
+ require ModPerl::Interpreter;
+ require ModPerl::InterpPool;
+ require ModPerl::TiPool;
+ require ModPerl::TiPoolConfig;
+
+ my $interp = ModPerl::Interpreter->current;
+
+ ok t_cmp(ref($interp), 'ModPerl::Interpreter',
+ 'interp is a ModPerl::Interpreter');
+
+ ok t_cmp($$interp==${ModPerl::Interpreter::current()}, !!1,
+ 'ModPerl::Interpreter->current == ModPerl::Interpreter::current');
+
+ my $mip = $interp->mip;
+
+ ok t_cmp(ref($mip), 'ModPerl::InterpPool',
+ 'interp->mip is a ModPerl::InterpPool');
+
+ ok t_cmp(${$mip->server}==${$r->server}, !!1,
+ 'mip->server == r->server');
+
+ ok t_cmp(ref($mip->parent), 'ModPerl::Interpreter',
+ 'mip->parent is a ModPerl::Interpreter');
+
+ if($is_threaded) {
+ ok t_cmp($interp->perl!=0, !!1, 'interp->perl');
+ ok t_cmp($interp->num_requests>0, !!1, 'interp->num_requests');
+ ok t_cmp($interp->refcnt>0, !!1, 'interp->refcnt');
+
+ my $tipool = $mip->tipool;
+
+ ok t_cmp(ref($tipool), 'ModPerl::TiPool',
+ 'mip->tipool is a ModPerl::TiPool');
+
+ ok t_cmp($tipool->in_use!=0, !!1, 'tipool->in_use');
+
+ ok t_cmp($tipool->size!=0, !!1, 'tipool->size');
+
+ my $tipcfg = $tipool->cfg;
+
+ ok t_cmp(ref($tipcfg), 'ModPerl::TiPoolConfig',
+ 'tipool->cfg is a ModPerl::TiPoolConfig');
+
+ ok t_cmp($tipcfg->start!=0, !!1, 'tipcfg->start');
+
+ ok t_cmp($tipcfg->min_spare!=0, !!1, 'tipcfg->min_spare');
+
+ ok t_cmp($tipcfg->max_spare!=0, !!1, 'tipcfg->max_spare');
+
+ ok t_cmp($tipcfg->max!=0, !!1, 'tipcfg->max');
+
+ ok t_cmp($tipcfg->max_requests!=0, !!1, 'tipcfg->max_requests');
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestModperl/io_nested_with_closed_stds.pm b/2_0_13/t/response/TestModperl/io_nested_with_closed_stds.pm
new file mode 100644
index 0000000..f87373c
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/io_nested_with_closed_stds.pm
@@ -0,0 +1,64 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::io_nested_with_closed_stds;
+
+# test that we can successfully override STD(IN|OUT) for
+# 'perl-script', even if they are closed. Here we use
+# internal_redirect(), which causes a nested override of already
+# overriden STD streams
+
+# in this test we can't use my $foo as a filehandle, since perl 5.6
+# doesn't know how to dup via: 'open STDIN, "<&", $oldin'
+# so use the old FOO filehandle style
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $args = $r->args || '';
+ if ($args eq 'redirect') {
+ # sub-req
+ $r->content_type('text/plain');
+ # do not use plan() here, since it messes up with STDOUT,
+ # which affects this test.
+ print "1..1\nok 1\n";
+ }
+ else {
+ # main-req
+ my $redirect_uri = $r->uri . "?redirect";
+
+ # we must close STDIN as well, due to a perl bug (5.8.0 - 5.8.3
+ # w/useperlio), which emits a warning if dup is called with
+ # one of the STD streams is closed.
+ # but we must restore the STD streams so not to affect other
+ # tests.
+ open OLDIN, "<&STDIN" or die "Can't dup STDIN: $!";
+ open OLDOUT, ">&STDOUT" or die "Can't dup STDOUT: $!";
+ close STDIN;
+ close STDOUT;
+
+ $r->internal_redirect($redirect_uri);
+
+ open STDIN, "<&OLDIN" or die "Can't dup OLDIN: $!";
+ open STDOUT, ">&OLDOUT" or die "Can't dup OLDOUT: $!";
+ close OLDIN;
+ close OLDOUT;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler perl-script
+
diff --git a/2_0_13/t/response/TestModperl/io_with_closed_stds.pm b/2_0_13/t/response/TestModperl/io_with_closed_stds.pm
new file mode 100644
index 0000000..b07a7cd
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/io_with_closed_stds.pm
@@ -0,0 +1,67 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::io_with_closed_stds;
+
+# test that we can successfully override STD(IN|OUT) for
+# 'perl-script', even if they are closed.
+
+# in this test we can't use my $foo as a filehandle, since perl 5.6
+# doesn't know how to dup via: 'open STDIN, "<&", $oldin'
+# so use the old FOO filehandle style, which is also global, so we
+# don't even need to pass it around (very bad code style, but I see no
+# better solution if we want to have this test run under perl 5.6)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub fixup {
+ my $r = shift;
+
+ # we must close STDIN as well, due to a perl bug (5.8.0 - 5.8.3
+ # w/useperlio), which emits a warning if dup is called with
+ # one of the STD streams is closed.
+ open OLDIN, "<&STDIN" or die "Can't dup STDIN: $!";
+ open OLDOUT, ">&STDOUT" or die "Can't dup STDOUT: $!";
+ close STDIN;
+ close STDOUT;
+
+ Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ ok 1;
+
+ Apache2::Const::OK;
+}
+
+sub cleanup {
+ my $r = shift;
+
+ # restore the STD(IN|OUT) streams so not to affect other tests.
+ open STDIN, "<&OLDIN" or die "Can't dup OLDIN: $!";
+ open STDOUT, ">&OLDOUT" or die "Can't dup OLDOUT: $!";
+ close OLDIN;
+ close OLDOUT;
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlModule TestModperl::io_with_closed_stds
+SetHandler perl-script
+PerlFixupHandler TestModperl::io_with_closed_stds::fixup
+PerlResponseHandler TestModperl::io_with_closed_stds
+PerlCleanupHandler TestModperl::io_with_closed_stds::cleanup
diff --git a/2_0_13/t/response/TestModperl/local_env.pm b/2_0_13/t/response/TestModperl/local_env.pm
new file mode 100644
index 0000000..ed18c6a
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/local_env.pm
@@ -0,0 +1,54 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::local_env;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+# local %ENV used to cause segfaults
+# Report: http://thread.gmane.org/gmane.comp.apache.mod-perl/22236
+# Fixed in: http://svn.apache.org/viewcvs.cgi?rev=357236&view=rev
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 6;
+
+ my %copy_ENV = %ENV; ## this is not a deep copy;
+
+ ok t_cmp($ENV{MOD_PERL_API_VERSION}, 2,
+ "\$ENV{MOD_PERL_API_VERSION} is 2 before local \%ENV");
+
+ {
+ local %ENV;
+
+ ok t_cmp($ENV{MOD_PERL_API_VERSION}, undef,
+ "\$ENV{MOD_PERL_API_VERSION} is undef after local \%ENV");
+
+ ok t_cmp(scalar keys %ENV, 0,
+ "\%ENV has 0 keys after local");
+
+ $ENV{LOCAL} = 1;
+
+ ok t_cmp($ENV{LOCAL}, 1,
+ "can set value after local, but still in block");
+ }
+
+ ok t_cmp($ENV{LOCAL}, undef,
+ "valuee set in local {} block is gone after leaving scope");
+
+ ok t_cmp(\%copy_ENV, \%ENV, "\%ENV was restored correctly");
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/merge.pm b/2_0_13/t/response/TestModperl/merge.pm
new file mode 100644
index 0000000..da4460a
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/merge.pm
@@ -0,0 +1,188 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::merge;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::ServerRec ();
+use Apache2::ServerUtil ();
+use Apache2::RequestUtil ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+# this is the configuration and handler for t/modperl/merge.t,
+# t/modperl/merge2.t, and t/modperl/merge3.t. see any of those
+# tests and/or the below configuration for more details
+
+# result tables for the below tests (trying to make the code more
+# simple...) the hash itself represents a request
+# the keys to the main hash represent merge levels - 1 for the
+# non-overriding merge, 2 for an overriding merge, and 3 for a
+# two-level merge the rest should be self-explanatory - settings and
+# expected values.
+our %merge1 = (
+ 1 => { PerlPassEnv => [APACHE_TEST_HOSTTYPE => 'z80'],
+ PerlSetEnv => [MergeSetEnv1 => 'SetEnv1Val'],
+ PerlSetVar => [MergeSetVar1 => 'SetVar1Val'],
+ PerlAddVar => [MergeAddVar1 => ['AddVar1Val1',
+ 'AddVar1Val2']],
+ },
+ 2 => { PerlSetEnv => [MergeSetEnv2 => 'SetEnv2Val'],
+ PerlSetVar => [MergeSetVar2 => 'SetVar2Val'],
+ PerlAddVar => [MergeAddVar2 => ['AddVar2Val1',
+ 'AddVar2Val2']],
+ },
+ 3 => { PerlSetEnv => [MergeSetEnv3 => 'SetEnv3Val'],
+ PerlSetVar => [MergeSetVar3 => 'SetVar3Val'],
+ PerlAddVar => [MergeAddVar3 => ['AddVar3Val1',
+ 'AddVar3Val2']],
+ },
+);
+
+our %merge2 = (
+ 1 => { PerlPassEnv => [APACHE_TEST_HOSTTYPE => 'z80'],
+ PerlSetEnv => [MergeSetEnv1 => 'SetEnv1Val'],
+ PerlSetVar => [MergeSetVar1 => 'SetVar1Val'],
+ PerlAddVar => [MergeAddVar1 => ['AddVar1Val1',
+ 'AddVar1Val2']],
+ },
+ 2 => { PerlSetEnv => [MergeSetEnv2 => 'SetEnv2Merge2Val'],
+ PerlSetVar => [MergeSetVar2 => 'SetVar2Merge2Val'],
+ PerlAddVar => [MergeAddVar2 => ['AddVar2Merge2Val1',
+ 'AddVar2Merge2Val2']],
+ },
+ 3 => { PerlSetEnv => [MergeSetEnv3 => 'SetEnv3Val'],
+ PerlSetVar => [MergeSetVar3 => 'SetVar3Val'],
+ PerlAddVar => [MergeAddVar3 => ['AddVar3Val1',
+ 'AddVar3Val2']],
+ },
+);
+
+our %merge3 = (
+ 1 => { PerlPassEnv => [APACHE_TEST_HOSTTYPE => 'z80'],
+ PerlSetEnv => [MergeSetEnv1 => 'SetEnv1Val'],
+ PerlSetVar => [MergeSetVar1 => 'SetVar1Val'],
+ PerlAddVar => [MergeAddVar1 => ['AddVar1Val1',
+ 'AddVar1Val2']],
+ },
+ 2 => { PerlSetEnv => [MergeSetEnv2 => 'SetEnv2Merge3Val'],
+ PerlSetVar => [MergeSetVar2 => 'SetVar2Merge3Val'],
+ PerlAddVar => [MergeAddVar2 => ['AddVar2Merge3Val1',
+ 'AddVar2Merge3Val2']],
+ },
+ 3 => { PerlSetEnv => [MergeSetEnv3 => 'SetEnv3Merge3Val'],
+ PerlSetVar => [MergeSetVar3 => 'SetVar3Merge3Val'],
+ PerlAddVar => [MergeAddVar3 => ['AddVar3Merge3Val1',
+ 'AddVar3Merge3Val2']],
+ },
+);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 10;
+
+ my $uri = $r->uri;
+ my $hash;
+
+ if ($uri =~ m/(merge3)/) {
+ $hash = $1;
+ } elsif ($uri =~ m/(merge2)/) {
+ $hash = $1;
+ } else {
+ $hash = 'merge1';
+ }
+
+ t_debug("testing against results in $hash");
+
+ no strict qw(refs);
+ foreach my $level (sort keys %$hash) {
+ foreach my $directive (sort keys %{ $hash->{$level} }) {
+ my $key = $hash->{$level}->{$directive}->[0];
+ my $value = $hash->{$level}->{$directive}->[1];
+
+ my @expected = ref $value ? @$value : $value;
+
+ my $comment = join ' ', $directive, $key, @expected;
+
+ if ($directive =~ m/Env/) {
+ my $received = $ENV{$key};
+ ok t_cmp($received, $expected[0], $comment);
+ }
+ elsif ($directive =~ m/Set/) {
+ my $received = $r->dir_config->get($key);
+ ok t_cmp($received, $expected[0], $comment);
+ }
+ else {
+ my @received = $r->dir_config->get($key);
+ ok t_cmp(\@received, \@expected, $comment);
+ }
+ }
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+ PerlModule TestModperl::merge
+
+ <VirtualHost TestModperl::merge>
+ # these should pass through all merges untouched
+ PerlPassEnv APACHE_TEST_HOSTTYPE
+ PerlSetEnv MergeSetEnv1 SetEnv1Val
+ PerlSetVar MergeSetVar1 SetVar1Val
+ PerlSetVar MergeAddVar1 AddVar1Val1
+ PerlAddVar MergeAddVar1 AddVar1Val2
+
+ # these are overridden in /merge2 and /merge3
+ PerlSetEnv MergeSetEnv2 SetEnv2Val
+ PerlSetVar MergeSetVar2 SetVar2Val
+ PerlSetVar MergeAddVar2 AddVar2Val1
+ PerlAddVar MergeAddVar2 AddVar2Val2
+
+ # these are overridden in /merge3 only
+ PerlSetEnv MergeSetEnv3 SetEnv3Val
+ PerlSetVar MergeSetVar3 SetVar3Val
+ PerlSetVar MergeAddVar3 AddVar3Val1
+ PerlAddVar MergeAddVar3 AddVar3Val2
+
+ <Location /merge>
+ # same as per-server level
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::merge
+ </Location>
+
+ <Location /merge2>
+ # overrides "2" values - "1" and "3" values left untouched
+ PerlSetEnv MergeSetEnv2 SetEnv2Merge2Val
+ PerlSetVar MergeSetVar2 SetVar2Merge2Val
+ PerlSetVar MergeAddVar2 AddVar2Merge2Val1
+ PerlAddVar MergeAddVar2 AddVar2Merge2Val2
+
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::merge
+ </Location>
+
+ AccessFileName htaccess
+ <Directory @DocumentRoot@/merge3>
+ # overrides "2" values
+ PerlSetEnv MergeSetEnv2 SetEnv2Merge3Val
+ PerlSetVar MergeSetVar2 SetVar2Merge3Val
+ PerlSetVar MergeAddVar2 AddVar2Merge3Val1
+ PerlAddVar MergeAddVar2 AddVar2Merge3Val2
+
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::merge
+
+ # override "3" values
+ AllowOverride all
+ </Directory>
+
+ </VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/method.pm b/2_0_13/t/response/TestModperl/method.pm
new file mode 100644
index 0000000..568784e
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/method.pm
@@ -0,0 +1,56 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::method;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+use Apache2::Const -compile => 'OK';
+
+sub new {
+ my $class = shift;
+
+ bless {
+ perl_version => $],
+ }, $class;
+}
+
+sub handler : method {
+ my ($self, $r) = @_;
+
+ my $tests = 3;
+
+ my $is_obj = ref($self);
+
+ if ($is_obj) {
+ $tests += 1;
+ }
+
+ plan $r, tests => $tests;
+
+ ok t_cmp(scalar @_, 2,
+ '@_ == 2');
+
+ my $class = ref($self) || $self;
+
+ ok t_cmp($class, $class,
+ 'handler class');
+
+ ok t_cmp(
+ $r->uri,
+ '/' . Apache::TestRequest::module2path($class),
+ '$r->uri eq $location');
+
+ if ($is_obj) {
+ ok t_cmp($self->{perl_version}, $],
+ 'object handler data');
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestModperl/methodname.pm b/2_0_13/t/response/TestModperl/methodname.pm
new file mode 100644
index 0000000..e5464a6
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/methodname.pm
@@ -0,0 +1,21 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::methodname;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+use TestModperl::method ();
+
+#no : method attribute required when -> config syntax is used
+sub response {
+ TestModperl::method::handler(@_);
+}
+
+1;
+__END__
+PerlResponseHandler TestModperl::methodname->response
diff --git a/2_0_13/t/response/TestModperl/methodobj.pm b/2_0_13/t/response/TestModperl/methodobj.pm
new file mode 100644
index 0000000..3d8f3af
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/methodobj.pm
@@ -0,0 +1,16 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::methodobj;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Const -compile => 'OK';
+
+use TestModperl::method ();
+
+our @ISA = qw(TestModperl::method);
+
+1;
+__END__
+PerlResponseHandler $TestModperl::MethodObj->handler
+
diff --git a/2_0_13/t/response/TestModperl/perl.pm b/2_0_13/t/response/TestModperl/perl.pm
new file mode 100644
index 0000000..a49c784
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/perl.pm
@@ -0,0 +1,30 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::perl;
+
+# this test includes tests for buggy Perl functions for which mod_perl
+# provides a workaround
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ ok t_cmp("SNXJvM5I.PJrE",
+ crypt("testing", "SNXJvM5I.PJrE"),
+ "crypt");
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+
+
diff --git a/2_0_13/t/response/TestModperl/perl_options.pm b/2_0_13/t/response/TestModperl/perl_options.pm
new file mode 100644
index 0000000..9908650
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/perl_options.pm
@@ -0,0 +1,63 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::perl_options;
+
+# test whether PerlOptions options are enabled
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use Apache2::ServerUtil ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+my @srv_plus = qw(ChildInit ChildExit Fixup);
+my @srv_minus = qw(PreConnection ProcessConnection Autoload
+ Log InputFilter OutputFilter);
+my @dir_plus = qw(ParseHeaders MergeHandlers);
+my @dir_minus = qw(SetupEnv GlobalRequest);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => @srv_plus + @srv_minus + @dir_plus + @dir_minus;
+ my $s = $r->server;
+
+ ok t_cmp($s->is_perl_option_enabled($_), 1,
+ "PerlOptions +$_") for @srv_plus;
+
+ ok t_cmp($s->is_perl_option_enabled($_), 0,
+ "PerlOptions -$_") for @srv_minus;
+
+ ok t_cmp($r->is_perl_option_enabled($_), 1,
+ "PerlOptions +$_") for @dir_plus;
+
+ ok t_cmp($r->is_perl_option_enabled($_), 0,
+ "PerlOptions -$_") for @dir_minus;
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<VirtualHost TestModperl::perl_options>
+ PerlOptions -PreConnection -ProcessConnection
+ PerlOptions -Autoload -Log -InputFilter -OutputFilter
+ PerlOptions +ChildInit +ChildExit
+ PerlModule TestModperl::perl_options
+ PerlOptions +ParseHeaders
+ <Location /TestModperl__perl_options>
+ SetHandler modperl
+ PerlOptions -GlobalRequest -SetupEnv
+ PerlOptions +MergeHandlers
+ PerlResponseHandler TestModperl::perl_options
+ </Location>
+</VirtualHost>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/response/TestModperl/perl_options2.pm b/2_0_13/t/response/TestModperl/perl_options2.pm
new file mode 100644
index 0000000..29f8a46
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/perl_options2.pm
@@ -0,0 +1,70 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::perl_options2;
+
+# test whether PerlOptions None works
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use Apache2::ServerUtil ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK);
+
+my @srv = qw(
+ OpenLogs
+ PostConfig
+ ChildInit
+ ChildExit
+
+ PreConnection
+ ProcessConnection
+
+ InputFilter
+ OutputFilter
+
+ PostReadRequest
+ Trans
+ MapToStorage
+ HeaderParser
+ Access
+ Authen
+ Authz
+ Type
+ Fixup
+ Log
+ Cleanup
+);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => scalar @srv, skip_reason('PerlOptions None is broken');
+
+ my $s = $r->server;
+
+ ok t_cmp($s->is_perl_option_enabled($_), 0,
+ "$_ is off under PerlOptions None") for @srv;
+
+ ok t_cmp($s->is_perl_option_enabled('Response'), 1,
+ "Response is off under PerlOptions None");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+<NoAutoConfig>
+<VirtualHost TestModperl::perl_options2>
+ PerlOptions None +Response
+ <Location /TestModperl__perl_options2>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::perl_options2
+ </Location>
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/pnotes.pm b/2_0_13/t/response/TestModperl/pnotes.pm
new file mode 100644
index 0000000..1a354aa
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/pnotes.pm
@@ -0,0 +1,127 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::pnotes;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestUtil ();
+use Apache2::ConnectionUtil ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ # make it ok to call ok() here while plan()ing elsewhere
+ Apache::Test::init_test_pm($r);
+
+ Test::_reset_globals() if Test->can('_reset_globals');
+ $Test::ntest = 1 + (26 * ($r->args - 1));
+ $Test::planned = 26;
+
+ my $c = $r->connection;
+
+ # we call this handler 3 times.
+ # $r->pnotes('request') should be unset each time
+ # $c->pnotes('connection') should be unset the first
+ # time but set the second time due to the keepalive
+ # request. the second request then cleans up after
+ # itself, leaving $c->pnotes again unset at the
+ # start of the third request
+ if ($r->args == 2) {
+ ok t_cmp($c->pnotes('connection'),
+ 'CSET',
+ '$c->pnotes() persists across keepalive requests');
+ }
+ else {
+ t_debug('testing $c->pnotes is empty');
+ ok (! $c->pnotes('connection'));
+ }
+
+ # $r->pnotes should be reset each time
+ t_debug('testing $r->pnotes is empty');
+ ok (! $r->pnotes('request'));
+
+ foreach my $map ({type => 'r', object => $r},
+ {type => 'c', object => $c}) {
+
+ my $type = $map->{type};
+
+ my $o = $map->{object};
+
+ t_debug("testing $type->pnotes call");
+ ok $o->pnotes;
+
+ ok t_cmp($o->pnotes('pnotes_foo', 'pnotes_bar'),
+ 'pnotes_bar',
+ "$type->pnotes(key,val)");
+
+ ok t_cmp($o->pnotes('pnotes_foo'),
+ 'pnotes_bar',
+ "$type->pnotes(key)");
+
+ ok t_cmp(ref($o->pnotes), 'HASH', "ref($type->pnotes)");
+
+ ok t_cmp($o->pnotes()->{'pnotes_foo'}, 'pnotes_bar',
+ "$type->pnotes()->{}");
+
+ # unset the entry (but the entry remains with undef value)
+ $o->pnotes('pnotes_foo', undef);
+ ok t_cmp($o->pnotes('pnotes_foo'), undef,
+ "unset $type contents");
+
+ my $exists = exists $o->pnotes->{'pnotes_foo'};
+ $exists = 1 if $] < 5.008001; # changed in perl 5.8.1
+ ok $exists;
+
+ # now delete completely (possible only via the hash inteface)
+ delete $o->pnotes()->{'pnotes_foo'};
+ ok t_cmp($o->pnotes('pnotes_foo'), undef,
+ "deleted $type contents");
+ ok !exists $o->pnotes->{'pnotes_foo'};
+
+ # test blessed references, like DBI
+ # DBD::DBM ships with DBI...
+ if (have_module(qw(DBI DBD::DBM))) {
+ my $dbh = DBI->connect('dbi:DBM:');
+
+ $o->pnotes(DBH => $dbh);
+
+ my $pdbh = $o->pnotes('DBH');
+
+ ok t_cmp(ref($pdbh), 'DBI::db', "ref($type->pnotes('DBH'))");
+
+ my $quote = $pdbh->quote("quoth'me");
+
+ # see the DBI manpage for why quote() returns the string
+ # wrapped in ' marks
+ ok t_cmp($quote, "'quoth\\'me'", '$pdbh->quote() works');
+ }
+ else {
+ skip ('skipping $dbh retrival test - no DBI or DBD::DBM');
+ skip ('skipping $dbh->quote() test - no DBI or DBD::DBM');
+ }
+ }
+
+ # set pnotes so we can test unset on later connections
+ $r->pnotes(request => 'RSET');
+ $c->pnotes(connection => 'CSET');
+
+ ok t_cmp($r->pnotes('request'),
+ 'RSET',
+ '$r->pnotes() set');
+
+ ok t_cmp($c->pnotes('connection'),
+ 'CSET',
+ '$c->pnotes() set');
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+
+
diff --git a/2_0_13/t/response/TestModperl/pnotes2.pm b/2_0_13/t/response/TestModperl/pnotes2.pm
new file mode 100644
index 0000000..fd3d14a
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/pnotes2.pm
@@ -0,0 +1,85 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::pnotes2;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Log ();
+use Apache2::RequestUtil ();
+use Apache2::ConnectionUtil ();
+
+use Apache2::Const -compile => 'OK';
+
+{
+ package TestModerl::pnotes2::x;
+ use strict;
+ use warnings FATAL => 'all';
+
+ sub new {shift;bless [@_];}
+ sub DESTROY {my $f=shift @{$_[0]}; $f->(@{$_[0]});}
+}
+
+sub line {
+ our $cleanup;
+
+ Apache2::ServerRec::warn "pnotes are destroyed after cleanup ".$cleanup;
+}
+
+sub cleanup {
+ our $cleanup;
+ $cleanup='passed';
+
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ our $cleanup;
+ $cleanup='';
+
+ $r->push_handlers( PerlCleanupHandler=>__PACKAGE__.'::cleanup' );
+
+ if(!defined $r->args) {
+ } elsif($r->args == 1) {
+ $r->pnotes(x1 => TestModerl::pnotes2::x->new(\&line));
+ } elsif($r->args == 2) {
+ $r->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line);
+ } elsif($r->args == 3) {
+ $r->pnotes(x1 => TestModerl::pnotes2::x->new(\&line));
+ $r->pnotes(x2 => 2);
+ } elsif($r->args == 4) {
+ $r->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line);
+ $r->pnotes->{x2} = 2;
+ } elsif($r->args == 5) {
+ $r->pnotes(x1 => TestModerl::pnotes2::x->new(\&line));
+ $r->pnotes->{x2} = 2;
+ } elsif($r->args == 6) {
+ $r->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line);
+ $r->pnotes(x2 => 2);
+ } elsif($r->args == 7) {
+ $r->connection->pnotes(x1 => TestModerl::pnotes2::x->new(\&line));
+ } elsif($r->args == 8) {
+ $r->connection->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line);
+ } elsif($r->args == 9) {
+ $r->connection->pnotes(x1 => TestModerl::pnotes2::x->new(\&line));
+ $r->connection->pnotes(x2 => 2);
+ } elsif($r->args == 10) {
+ $r->connection->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line);
+ $r->connection->pnotes->{x2} = 2;
+ } elsif($r->args == 11) {
+ $r->connection->pnotes(x1 => TestModerl::pnotes2::x->new(\&line));
+ $r->connection->pnotes->{x2} = 2;
+ } elsif($r->args == 12) {
+ $r->connection->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line);
+ $r->connection->pnotes(x2 => 2);
+ }
+
+ $r->content_type('text/plain');
+ $r->print("OK");
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestModperl/post_utf8.pm b/2_0_13/t/response/TestModperl/post_utf8.pm
new file mode 100644
index 0000000..48d7aa2
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/post_utf8.pm
@@ -0,0 +1,68 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::post_utf8;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use APR::Table ();
+
+use TestCommon::Utils ();
+
+use Apache2::Const -compile => 'OK';
+
+my $expected_ascii = "I love you, (why lying?), but I belong to another";
+my $expected_utf8 = "\x{042F} \x{0432}\x{0430}\x{0441} \x{043B}\x{044E}" .
+ "\x{0431}\x{043B}\x{044E} (\x{043A} \x{0447}\x{0435}\x{043C}\x{0443} " .
+ "\x{043B}\x{0443}\x{043A}\x{0430}\x{0432}\x{0438}\x{0442}\x{044C}?),\n" .
+ "\x{041D}\x{043E} \x{044F} \x{0434}\x{0440}\x{0443}\x{0433}\x{043E}" .
+ "\x{043C}\x{0443} \x{043E}\x{0442}\x{0434}\x{0430}\x{043D}\x{0430};";
+
+sub handler {
+ my $r = shift;
+
+# # visual debug, e.g. in lynx/mozilla
+# $r->content_type("text/plain; charset=utf-8");
+# $r->print("expected: $expected_utf8\n");
+
+ my $received = TestCommon::Utils::read_post($r) || "";
+
+ # utf encode/decode was added only in 5.8.0
+ # XXX: currently binmode is only available with perlio (used on the
+ # server side on the tied/perlio STDOUT)
+ plan $r, tests => 2,
+ need need_min_perl_version(5.008), need_perl('perlio');
+
+ # workaround for perl-5.8.0, which doesn't decode correctly a
+ # tainted variable
+ require ModPerl::Util;
+ ModPerl::Util::untaint($received) if $] == 5.008;
+
+ # assume that we know that it's utf8
+ require Encode; # since 5.8.0
+ $received = Encode::decode('utf8', $received);
+ # utf8::decode() doesn't work under -T
+ my ($received_ascii, $received_utf8) = split /=/, $received;
+
+ ok t_cmp($received_ascii, $expected_ascii, "ascii");
+
+ ok $expected_utf8 eq $received_utf8;
+ # if you want to see the utf8 data run with:
+ # t/TEST -trace=debug -v modperl/post_utf8
+ # and look for this data in t/logs/error_log
+ # needed for sending utf-8 to STDERR for debug
+ binmode(STDERR, ':utf8');
+ debug "expected: $expected_utf8";
+ debug "received: $received_utf8";
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/print.pm b/2_0_13/t/response/TestModperl/print.pm
new file mode 100644
index 0000000..64d8968
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/print.pm
@@ -0,0 +1,49 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::print;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 6;
+
+ binmode STDOUT; #Apache2::RequestRec::BINMODE (noop)
+
+ ok 1;
+
+ ok 2;
+
+ {
+ # print should return true on success, even
+ # if it sends no data.
+ my $rc = print '';
+
+ ok ($rc);
+ ok ($rc == 0); # 0E0 is still numerically 0
+ }
+
+ {
+ my $rc = print "# 11 bytes\n"; # don't forget the newline
+
+ ok ($rc == 11);
+ }
+
+ printf "ok %d\n", 6;
+
+ Apache2::Const::OK;
+}
+
+END {
+ my $package = __PACKAGE__;
+ warn "END in $package, pid=$$\n";
+}
+
+1;
diff --git a/2_0_13/t/response/TestModperl/print_utf8.pm b/2_0_13/t/response/TestModperl/print_utf8.pm
new file mode 100644
index 0000000..f95ca48
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/print_utf8.pm
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::print_utf8;
+
+# testing the utf8-encoded response via a tied STDOUT/perlio STDOUT,
+# the latter if perl was built with perlio.
+# see Modperl/print_utf8_2.pm for $r->print
+
+# must test against a tied STDOUT/perlio STDOUT. $r->print does the
+# right thing without any extra provisions
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain; charset=UTF-8');
+
+ # prevent warning: "Wide character in print"
+ binmode(STDOUT, ':utf8'); # Apache2::RequestRec::BINMODE()
+
+ # must be non-$r->print(), so we go through the tied STDOUT
+ # \x{263A} == :-)
+ print "Hello Ayhan \x{263A} perlio rules!";
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/print_utf8_2.pm b/2_0_13/t/response/TestModperl/print_utf8_2.pm
new file mode 100644
index 0000000..423c7de
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/print_utf8_2.pm
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::print_utf8_2;
+
+# testing the utf8-encoded response via direct $r->print, which does the
+# right thing without any extra provisions.
+# see print_utf8.pm for tied STDOUT/perlio STDOUT, which requires extra work
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain; charset=UTF-8');
+
+ # \x{263A} == :-)
+ $r->print("\$r->print() just works \x{263A}");
+
+ Apache2::Const::OK;
+}
+
+1;
+__DATA__
+SetHandler modperl
diff --git a/2_0_13/t/response/TestModperl/printf.pm b/2_0_13/t/response/TestModperl/printf.pm
new file mode 100644
index 0000000..54b1e89
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/printf.pm
@@ -0,0 +1,63 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::printf;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+use APR::Table ();
+
+use Apache2::Const -compile => qw(OK);
+
+sub handler {
+ my $r = shift;
+
+ my $tests = 4;
+
+ $r->printf("1..%d\n", $tests);
+
+ # ok 1
+ $r->printf("ok");
+ $r->printf(" %d\n", 1);
+
+ # ok 2
+ my $fmt = "%s%s %d\n";
+ $r->printf($fmt, qw(o k), 2);
+
+ # ok 3
+ my @a = ("ok %d%c", 3, ord("\n"));
+ $r->PRINTF(@a);
+
+ # ok 4 (gets input from the fixup handler via notes)
+ {
+ my $note = $r->notes->get("fixup") || '';
+ my $ok = $note =~
+ /\$r->printf can't be called before the response phase/;
+ $r->print("not ") unless $ok;
+ $r->print("ok 4\n");
+ $r->print("# either fixup was successful at printing to the\n",
+ "# client (which shouldn't happen before the\n",
+ "# response phase), or the note was lost/never set\n")
+ unless $ok;
+ $r->notes->clear;
+ }
+
+ Apache2::Const::OK;
+}
+
+sub fixup {
+ my $r = shift;
+
+ # it's not possible to send a response body before the response
+ # phase
+ eval { $r->printf("whatever") };
+ $r->notes->set(fixup => "$@") if $@;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+PerlModule TestModperl::printf
+PerlFixupHandler TestModperl::printf::fixup
diff --git a/2_0_13/t/response/TestModperl/readline.pm b/2_0_13/t/response/TestModperl/readline.pm
new file mode 100644
index 0000000..705cf0f
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/readline.pm
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::readline;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+use Apache2::compat (); #XXX
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ untie *STDIN;
+ tie *STDIN, $r;
+
+ while (defined(my $line = <STDIN>)) {
+ $r->puts($line);
+ }
+
+ untie *STDIN;
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestModperl/request_rec_perlio_api.pm b/2_0_13/t/response/TestModperl/request_rec_perlio_api.pm
new file mode 100644
index 0000000..c8a225f
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/request_rec_perlio_api.pm
@@ -0,0 +1,105 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::request_rec_perlio_api;
+
+# this test is relevant only when the PerlIO STDIN/STDOUT are used (when
+# $Config{useperlio} is defined.)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+
+use Apache::Test;
+
+use File::Spec::Functions qw(catfile catdir);
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->args eq 'STDIN' ? test_STDIN($r) : test_STDOUT($r);
+
+ return Apache2::Const::OK;
+}
+
+sub test_STDIN {
+ my $r = shift;
+
+ {
+ # read the first 10 POST chars
+ my $data;
+ read STDIN, $data, 10;
+ print STDOUT $data;
+ }
+
+ {
+ # re-open STDIN to something else, and then see if we don't
+ # lose any chars when we restore it to the POST stream
+ open my $stdin, "<&STDIN" or die "Can't dup STDIN: $!";
+
+ open STDIN, "<", __FILE__
+ or die "failed to open STDIN as 'in memory' file : $!";
+ my $data;
+ read STDIN, $data, length("# please");
+ print STDOUT $data;
+ close STDIN;
+
+ open STDIN, "<&", $stdin or die "failed to restore STDIN: $!";
+ }
+
+ {
+ # read the last 10 POST chars
+ my $data;
+ read STDIN, $data, 10;
+ print STDOUT $data;
+ }
+
+}
+
+sub test_STDOUT {
+ my $r = shift;
+
+ local $| = 0;
+ print STDOUT "life is hard ";
+
+ my $vars = Apache::Test::config()->{vars};
+ my $target_dir = catdir $vars->{documentroot}, 'perlio';
+ my $file = catfile $target_dir, "apache_stdout";
+
+ # re-open STDOUT to something else, and then see if we can
+ # continue printing to the client via STDOUT, after restoring it
+ open my $stdout, ">&STDOUT" or die "Can't dup STDOUT: $!";
+
+ # this should flush the above print to STDOUT
+ open STDOUT, ">", $file or die "Can't open $file: $!";
+ print STDOUT "and then ";
+ close STDOUT;
+
+ # flush things that went into the file as STDOUT
+ open STDOUT, ">&", $stdout or die "failed to restore STDOUT: $!";
+ open my $fh, $file or die "Can't open $file: $!";
+ local $\;
+ print <$fh>;
+
+ # cleanup
+ unlink $file;
+
+ # close the dupped fh
+ close $stdout;
+
+ print "you die! ";
+
+ # now close it completely and restore it, without using any dupped
+ # filehandle
+ close STDOUT;
+ open STDOUT, ">:Apache2", $r
+ or die "can't open STDOUT via :Apache2 layer : $!";
+ print "next you reincarnate...";
+
+}
+
+1;
+__DATA__
+SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/request_rec_tie_api.pm b/2_0_13/t/response/TestModperl/request_rec_tie_api.pm
new file mode 100644
index 0000000..d27c44e
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/request_rec_tie_api.pm
@@ -0,0 +1,68 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::request_rec_tie_api;
+
+# this test is relevant only when the tied STDIN/STDOUT are used (when
+# $Config{useperlio} is not defined.)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestIO ();
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestConfig;
+
+use File::Spec::Functions qw(catfile catdir);
+
+use Apache2::Const -compile => 'OK';
+
+use Config;
+
+sub handler {
+ my $r = shift;
+
+ require Apache2::Build;
+ my @todo;
+ push @todo, 1 if Apache2::Build::AIX();
+ plan $r, tests => 3, todo => \@todo,
+ need { "perl $]: PerlIO is used instead of TIEd IO"
+ => !($] >= 5.008 && $Config{useperlio}) };
+
+ # XXX: on AIX 4.3.3 we get:
+ # STDIN STDOUT STDERR
+ # perl : 0 1 2
+ # mod_perl: 0 0 2
+ my $fileno = fileno STDOUT;
+ ok $fileno;
+ t_debug "fileno STDOUT: $fileno";
+
+ {
+ my $vars = Apache::Test::config()->{vars};
+ my $target_dir = catdir $vars->{serverroot}, 'logs';
+ my $file = catfile $target_dir, "stdout";
+
+ # test OPEN
+ my $received = open STDOUT, ">", $file or die "Can't open $file: $!";
+ ok t_cmp($received, 1, "OPEN");
+
+ # test CLOSE, which is a noop
+ ok $r->CLOSE;
+ close $file;
+
+ # restore the tie
+ tie *STDOUT, $r;
+
+ # flush things that went into the file as STDOUT
+ open my $fh, $file or die "Can't open $file: $!";
+ local $\;
+ print <$fh>;
+
+ # cleanup
+ unlink $file;
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestModperl/setauth.pm b/2_0_13/t/response/TestModperl/setauth.pm
new file mode 100644
index 0000000..ce992cd
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/setauth.pm
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::setauth;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Access ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 2;
+
+ ok t_cmp($r->auth_type(), "none", 'auth_type');
+
+ t_server_log_error_is_expected();
+ $r->get_basic_auth_pw();
+
+ ok t_cmp($r->auth_type(), 'Basic', 'default auth_type');
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestModperl/setupenv.pm b/2_0_13/t/response/TestModperl/setupenv.pm
new file mode 100644
index 0000000..7dbcf9a
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/setupenv.pm
@@ -0,0 +1,343 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::setupenv;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use APR::Table ();
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => qw(OK DECLINED);
+
+sub handler {
+
+ my $r = shift;
+
+ # how many different URIs will be hit?
+ my $requests = $r->args;
+
+ # $requests locations with 7 tests each
+ plan $r, tests => $requests * 7;
+
+ return Apache2::Const::OK;
+}
+
+sub env {
+
+ my $r = shift;
+
+ Apache::Test::init_test_pm($r); # tie STDOUT
+
+ (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/;
+
+ ok t_cmp($ENV{REMOTE_ADDR},
+ Apache::Test::vars('remote_addr'),
+ 'found REMOTE_ADDR in %ENV');
+
+ ok t_cmp($ENV{SRV_SUBPROCESS},
+ 'server',
+ 'found subprocess_env table entry SRV_SUBPROCESS in %ENV');
+
+ ok t_cmp($ENV{DIR_SUBPROCESS},
+ $value,
+ 'found subprocess_env table entry DIR_SUBPROCESS in %ENV');
+
+ ok t_cmp($ENV{DIR_SETENV},
+ $value,
+ 'found per-directory SetEnv entry in %ENV');
+
+ ok t_cmp($ENV{SRV_SETENV},
+ 'server',
+ 'found per-server SetEnv entry in %ENV');
+
+ # PerlSetEnv always set
+ ok t_cmp($ENV{DIR_PERLSETENV},
+ $value,
+ 'found per-directory PerlSetEnv entry in %ENV');
+
+ ok t_cmp($ENV{SRV_PERLSETENV},
+ 'server',
+ 'found per-server PerlSetEnv entry in %ENV');
+
+ return Apache2::Const::OK;
+}
+
+sub noenv {
+
+ my $r = shift;
+
+ Apache::Test::init_test_pm($r); # tie STDOUT
+
+ (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/;
+
+ ok t_cmp($ENV{REMOTE_ADDR},
+ undef,
+ 'REMOTE_ADDR not found in %ENV');
+
+ ok t_cmp($ENV{SRV_SUBPROCESS},
+ undef,
+ 'subprocess_env table entry SRV_SUBPROCESS not found in %ENV');
+
+ ok t_cmp($ENV{DIR_SUBPROCESS},
+ undef,
+ 'subprocess_env table entry DIR_SUBPROCESS not found in %ENV');
+
+ ok t_cmp($ENV{DIR_SETENV},
+ undef,
+ 'per-directory SetEnv entry not found in %ENV');
+
+ ok t_cmp($ENV{SRV_SETENV},
+ undef,
+ 'per-server SetEnv entry not found in %ENV');
+
+ # PerlSetEnv always set
+ ok t_cmp($ENV{DIR_PERLSETENV},
+ $value,
+ 'found per-directory PerlSetEnv entry in %ENV');
+
+ ok t_cmp($ENV{SRV_PERLSETENV},
+ 'server',
+ 'found per-server PerlSetEnv entry in %ENV');
+
+ return Apache2::Const::OK;
+}
+
+sub someenv {
+
+ my $r = shift;
+
+ Apache::Test::init_test_pm($r); # tie STDOUT
+
+ (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/;
+
+ ok t_cmp($ENV{REMOTE_ADDR},
+ Apache::Test::vars('remote_addr'),
+ 'found REMOTE_ADDR in %ENV');
+
+ # set before void call
+ ok t_cmp($ENV{SRV_SUBPROCESS},
+ 'server',
+ 'found subprocess_env table entry one in %ENV');
+
+ ok t_cmp($ENV{DIR_SUBPROCESS},
+ undef,
+ 'subprocess_env table entry DIR_SUBPROCESS not found in %ENV');
+
+ ok t_cmp($ENV{DIR_SETENV},
+ undef,
+ 'per-directory SetEnv entry not found in %ENV');
+
+ ok t_cmp($ENV{SRV_SETENV},
+ undef,
+ 'per-server SetEnv entry not found in %ENV');
+
+ # PerlSetEnv always set
+ ok t_cmp($ENV{DIR_PERLSETENV},
+ $value,
+ 'found per-directory PerlSetEnv entry in %ENV');
+
+ ok t_cmp($ENV{SRV_PERLSETENV},
+ 'server',
+ 'found per-server PerlSetEnv entry in %ENV');
+
+ return Apache2::Const::OK;
+}
+
+sub subenv_void {
+
+ shift->subprocess_env;
+
+ return Apache2::Const::OK;
+}
+
+sub subenv_one {
+
+ shift->subprocess_env->set(SRV_SUBPROCESS => 'server');
+
+ return Apache2::Const::OK;
+}
+
+sub subenv_two {
+
+ my $r = shift;
+
+ (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/;
+
+ $r->subprocess_env->set(DIR_SUBPROCESS => $value);
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+# create a separate virtual host so we can use
+# keepalives - a per-connection interpreter is
+# the only way to make sure that we can plan in
+# one request and test in subsequent tests
+<NoAutoConfig>
+<VirtualHost TestModperl::setupenv>
+
+ KeepAlive On
+
+# <IfDefine PERL_USEITHREADS>
+# PerlInterpScope connection
+# </Ifdefine>
+
+ PerlModule TestModperl::setupenv
+
+ PerlPostReadRequestHandler TestModperl::setupenv::subenv_one
+
+ # SetEnv is affected by +SetupEnv
+ <IfModule mod_env.c>
+ SetEnv SRV_SETENV server
+ </IfModule>
+
+ # PerlSetEnv is not affected by +SetupEnv or -SetupEnv
+ # it is entirely separate and always set if configured
+ PerlSetEnv SRV_PERLSETENV server
+
+ # plan
+ <Location /TestModperl__setupenv>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::setupenv
+ </Location>
+
+ # default modperl handler
+ # %ENV should not contain standard CGI variables
+ # or entries from the subprocess_env table
+ <Location /TestModperl__setupenv_mpdefault>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::setupenv::noenv
+
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV mpdefault
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV mpdefault
+ </Location>
+
+ # modperl handler + SetupEnv
+ # %ENV should contain CGI variables as well as
+ # anything put into the subprocess_env table
+ <Location /TestModperl__setupenv_mpsetup>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::setupenv::env
+
+ PerlOptions +SetupEnv
+
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV mpsetup
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV mpsetup
+ </Location>
+
+ # $r->subprocess_env in a void context with no args
+ # should do the same as +SetupEnv wrt CGI variables
+ # and entries already in the subprocess_env table
+ # but subprocess_env entries that appear later will
+ # not show up in %ENV
+ <Location /TestModperl__setupenv_mpvoid>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::setupenv::someenv
+
+ PerlHeaderParserHandler TestModperl::setupenv::subenv_void
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV mpvoid
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV mpvoid
+ </Location>
+
+ # +SetupEnv should always populate %ENV fully prior
+ # to running the content handler (regardless of when
+ # $r->subprocess_env() was called) to ensure that
+ # %ENV is an accurate representation of the
+ # subprocess_env table
+ <Location /TestModperl__setupenv_mpsetupvoid>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::setupenv::env
+
+ PerlOptions +SetupEnv
+
+ PerlHeaderParserHandler TestModperl::setupenv::subenv_void
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV mpsetupvoid
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV mpsetupvoid
+ </Location>
+
+ # default perl-script handler is equivalent to +SetupEnv
+ # CGI variables and subprocess_env entries will be in %ENV
+ <Location /TestModperl__setupenv_psdefault>
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::setupenv::env
+
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV psdefault
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV psdefault
+ </Location>
+
+ # -SetupEnv should not put CGI variables or subprocess_env
+ # entries in %ENV
+ <Location /TestModperl__setupenv_psnosetup>
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::setupenv::noenv
+
+ PerlOptions -SetupEnv
+
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV psnosetup
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV psnosetup
+ </Location>
+
+ # +SetupEnv should always populate %ENV fully prior
+ # to running the content handler (regardless of when
+ # $r->subprocess_env() was called) to ensure that
+ # %ENV is an accurate representation of the
+ # subprocess_env table
+ <Location /TestModperl__setupenv_psvoid>
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::setupenv::env
+
+ PerlHeaderParserHandler TestModperl::setupenv::subenv_void
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV psvoid
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV psvoid
+ </Location>
+
+ # equivalent to modperl handler with $r->subprocess_env() -
+ # CGI variables are there, but not subprocess_env entries
+ # that are populated after the void call
+ <Location /TestModperl__setupenv_psnosetupvoid>
+ SetHandler perl-script
+ PerlResponseHandler TestModperl::setupenv::someenv
+
+ PerlOptions -SetupEnv
+
+ PerlHeaderParserHandler TestModperl::setupenv::subenv_void
+ PerlFixupHandler TestModperl::setupenv::subenv_two
+
+ <IfModule mod_env.c>
+ SetEnv DIR_SETENV psnosetupvoid
+ </IfModule>
+ PerlSetEnv DIR_PERLSETENV psnosetupvoid
+ </Location>
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/setupenv2.pm b/2_0_13/t/response/TestModperl/setupenv2.pm
new file mode 100644
index 0000000..bb27314
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/setupenv2.pm
@@ -0,0 +1,135 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::setupenv2;
+
+# Test the mixing of PerlSetEnv in httpd.conf and %ENV of the same
+# key in PerlRequire, PerlConfigRequire, PerlPostConfigRequire and
+# <Perl> sections
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::Const -compile => qw(OK OR_ALL NO_ARGS);
+
+use Apache2::CmdParms ();
+use Apache2::Module ();
+use Apache2::RequestIO ();
+use Apache2::RequestRec ();
+
+my @directives = (
+ {
+ name => 'MyEnvRegister',
+ func => __PACKAGE__ . '::MyEnvRegister',
+ req_override => Apache2::Const::OR_ALL,
+ args_how => Apache2::Const::NO_ARGS,
+ errmsg => 'cannot fail :)',
+ },
+);
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+# testing PerlLoadModule
+$ENV{EnvChangeMixedTest} = 'loadmodule';
+$ENV{EnvChangePerlTest} = 'loadmodule';
+
+sub MyEnvRegister {
+ register_mixed();
+}
+
+sub register_mixed {
+ push @TestModperl::setupenv2::EnvChangeMixedTest,
+ $ENV{EnvChangeMixedTest} || 'notset';
+}
+
+sub register_perl {
+ push @TestModperl::setupenv2::EnvChangePerlTest,
+ $ENV{EnvChangePerlTest} || 'notset';
+}
+
+sub get_config {
+ my ($self, $s) = (shift, shift);
+ Apache2::Module::get_config($self, $s, @_);
+}
+
+sub handler {
+ my ($r) = @_;
+
+ my $args = $r->args || '';
+
+ $r->content_type('text/plain');
+
+ if ($args eq 'mixed') {
+ my @vals = (@TestModperl::setupenv2::EnvChangeMixedTest,
+ $ENV{EnvChangeMixedTest}); # what's the latest env value
+ $r->print(join " ", @vals);
+ }
+ elsif ($args eq 'perl') {
+ my @vals = (@TestModperl::setupenv2::EnvChangePerlTest,
+ $ENV{EnvChangePerlTest}); # what's the latest env value
+ $r->print(join " ", @vals);
+ }
+ else {
+ die "no such case";
+ }
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<NoAutoConfig>
+PerlLoadModule TestModperl::setupenv2
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf1"
+
+<Perl >
+TestModperl::setupenv2::register_mixed();
+TestModperl::setupenv2::register_perl();
+$ENV{EnvChangeMixedTest} = "<perl>";
+$ENV{EnvChangePerlTest} = "<perl>";
+</Perl>
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf2"
+
+PerlRequire "@documentroot@/modperl/setupenv2/require.pl"
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf3"
+
+PerlConfigRequire "@documentroot@/modperl/setupenv2/config_require.pl"
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf4"
+
+PerlModule htdocs::modperl::setupenv2::module
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf5"
+MyEnvRegister
+
+PerlPostConfigRequire "@documentroot@/modperl/setupenv2/post_config_require.pl"
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf6"
+MyEnvRegister
+
+PerlSetEnv EnvChangeMixedTest "conf7"
+MyEnvRegister
+
+<Location /TestModperl__setupenv2>
+ SetHandler modperl
+ PerlResponseHandler TestModperl::setupenv2
+</Location>
+
+PerlSetEnv EnvChangeMixedTest "conf8"
+
+# Since PerlPostConfigRequire runs in the post-config phase it will
+# see 'conf8'. And when it sets that value to 'post_config_require' at
+# request time $ENV{EnvChangeMixedTest} will see the value set by
+# PerlPostConfigRequire.
+
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/status.pm b/2_0_13/t/response/TestModperl/status.pm
new file mode 100644
index 0000000..26964db
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/status.pm
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::status;
+
+use strict;
+use warnings;
+
+use Apache2::RequestRec;
+use Apache2::Const -compile => qw(DECLINED);
+
+use ModPerl::Util;
+use Apache::TestUtil qw(t_server_log_error_is_expected);
+
+sub handler {
+
+ my $rc = shift->args;
+
+ if ($rc eq 'die' ||
+ $rc eq Apache2::Const::DECLINED ||
+ $rc =~ m/foo/) {
+ t_server_log_error_is_expected();
+ }
+
+ ModPerl::Util::exit if $rc eq 'exit';
+
+ die if $rc eq 'die';
+
+ return if $rc eq 'undef';
+
+ return $rc;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestModperl/stdfd.pm b/2_0_13/t/response/TestModperl/stdfd.pm
new file mode 100644
index 0000000..906bbaf
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/stdfd.pm
@@ -0,0 +1,41 @@
+package TestModperl::stdfd;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache2::Const -compile => 'OK';
+
+sub fixup {
+ my $r = shift;
+
+ $r->handler($r->main ? 'perl-script' : 'modperl');
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ return Apache2::Const::OK if $r->main;
+
+ my @fds=(fileno(STDIN), fileno(STDOUT));
+
+ $r->lookup_uri($r->uri)->run;
+
+ $r->print("1..2\n");
+ $r->print((fileno(STDIN)==$fds[0] ? '' : 'not ').
+ "ok 1 - fileno(STDIN)=".fileno(STDIN)." expected $fds[0]\n");
+ $r->print((fileno(STDOUT)==$fds[1] ? '' : 'not ').
+ "ok 2 - fileno(STDOUT)=".fileno(STDOUT)." expected $fds[1]\n");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlModule TestModperl::stdfd
+PerlFixupHandler TestModperl::stdfd::fixup
+PerlResponseHandler TestModperl::stdfd
diff --git a/2_0_13/t/response/TestModperl/stdfd2.pm b/2_0_13/t/response/TestModperl/stdfd2.pm
new file mode 100644
index 0000000..b99ccf1
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/stdfd2.pm
@@ -0,0 +1,44 @@
+package TestModperl::stdfd2;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::SubRequest ();
+
+use Apache2::Const -compile => 'OK';
+
+sub fixup {
+ my $r = shift;
+
+ $r->handler($r->main ? 'perl-script' : 'modperl');
+ return Apache2::Const::OK;
+}
+
+sub handler {
+ my $r = shift;
+
+ return Apache2::Const::OK if $r->main;
+
+ local *STDIN;
+ open STDIN, '<', $INC{'TestModperl/stdfd2.pm'}
+ or die "Cannot open $INC{'TestModperl/stdfd2.pm'}";
+ scalar readline STDIN for(1..2);
+
+ my $expected=$.;
+
+ $r->lookup_uri($r->uri)->run;
+
+ $r->print("1..1\n");
+ $r->print(($.==$expected ? '' : 'not ').
+ "ok 1 - \$.=$. expected $expected\n");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__DATA__
+PerlModule TestModperl::stdfd2
+PerlFixupHandler TestModperl::stdfd2::fixup
+PerlResponseHandler TestModperl::stdfd2
diff --git a/2_0_13/t/response/TestModperl/subenv.pm b/2_0_13/t/response/TestModperl/subenv.pm
new file mode 100644
index 0000000..bd02d4b
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/subenv.pm
@@ -0,0 +1,118 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::subenv;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use APR::Table ();
+
+use Apache::Test;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+
+ my $r = shift;
+
+ plan $r, tests => 31;
+
+ # subprocess_env in void context with arguments does
+ # nothing to %ENV
+ {
+ my $env = $r->subprocess_env;
+
+ my $key = 'ONCE';
+
+ ok_false($r, $key);
+
+ $r->subprocess_env($key => 1); # void context but with args
+
+ ok_true($r, $key);
+
+ ok ! $ENV{$key}; # %ENV not populated yet
+ }
+
+ # subprocess_env in void context with no arguments
+ # populates the same as +SetEnv
+ {
+ my $env = $r->subprocess_env;
+
+ my $key = 'REMOTE_ADDR';
+
+ ok_false($r, $key); # still not not there yet
+
+ ok ! $ENV{$key}; # %ENV not populated yet
+
+ $r->subprocess_env; # void context with no arguments
+
+ ok_true($r, $key);
+
+ ok $ENV{$key}; # mod_cgi emulation
+ }
+
+ # handlers can use a void context more than once to force
+ # population of %ENV with new table entries
+ {
+ my $env = $r->subprocess_env;
+
+ my $key = 'AGAIN';
+
+ $env->set($key => 1); # new table entry
+
+ ok_true($r, $key);
+
+ ok ! $ENV{$key}; # shouldn't affect %ENV yet
+
+ $r->subprocess_env; # now called in in void context twice
+
+ ok $ENV{$key}; # so %ENV is populated with new entry
+ }
+
+ {
+ my $env = $r->subprocess_env; # table may have been overlayed
+
+ my $key = 'FOO';
+
+ $env->set($key => 1); # direct call to set()
+
+ ok_true($r, $key);
+
+ ok ! $ENV{$key}; # shouldn't affect %ENV
+
+ $r->subprocess_env($key => undef);
+
+ ok_false($r, $key); # removed
+
+ $r->subprocess_env($key => 1);
+
+ ok_true($r, $key); # reset
+
+ ok ! $ENV{$key}; # still shouldn't affect %ENV
+ }
+
+ Apache2::Const::OK;
+}
+
+sub ok_true {
+ my ($r, $key) = @_;
+
+ my $env = $r->subprocess_env;
+ ok $env->get($key);
+ ok $env->{$key};
+ ok $r->subprocess_env($key);
+}
+
+sub ok_false {
+ my ($r, $key) = @_;
+
+ my $env = $r->subprocess_env;
+ ok ! $env->get($key);
+ ok ! $env->{$key};
+ ok ! $r->subprocess_env($key);
+}
+
+1;
+__END__
+PerlOptions -SetupEnv
+
diff --git a/2_0_13/t/response/TestModperl/taint.pm b/2_0_13/t/response/TestModperl/taint.pm
new file mode 100644
index 0000000..090c524
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/taint.pm
@@ -0,0 +1,41 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::taint;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestIO ();
+use Apache2::RequestUtil ();
+use Apache2::Build ();
+
+use Apache2::Const -compile => 'OK';
+
+my $build = Apache2::Build->build_config;
+
+sub handler {
+ my $r = shift;
+
+ my $tests = $build->{MP_COMPAT_1X} ? 4 : 2;
+
+ plan $r, tests => $tests;
+
+ ok t_cmp(${^TAINT}, 1, "\${^TAINT}");
+
+ eval { ${^TAINT} = 0 };
+ ok t_cmp($@, qr/read-only/, "\${^TAINT} is read-only");
+
+ if ($build->{MP_COMPAT_1X}) {
+ ok t_cmp($Apache2::__T, 1, "\$Apache2::__T");
+
+ eval { $Apache2::__T = 0 };
+ ok t_cmp($@, qr/read-only/, "\$Apache2::__T is read-only");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestModperl/util.pm b/2_0_13/t/response/TestModperl/util.pm
new file mode 100644
index 0000000..d622992
--- /dev/null
+++ b/2_0_13/t/response/TestModperl/util.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModperl::util;
+
+# Modperl::Util tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use ModPerl::Util ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ ok t_cmp ModPerl::Util::current_perl_id(), qr/0x\w+/,
+ "perl interpreter id";
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
diff --git a/2_0_13/t/response/TestModules/cgi.pm b/2_0_13/t/response/TestModules/cgi.pm
new file mode 100644
index 0000000..7fcf883
--- /dev/null
+++ b/2_0_13/t/response/TestModules/cgi.pm
@@ -0,0 +1,58 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::cgi;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use CGI ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ unless ($ENV{MOD_PERL}) {
+ die "\$ENV{MOD_PERL} is not set";
+ }
+
+ unless ($ENV{MOD_PERL_API_VERSION} == 2) {
+ die "\$ENV{MOD_PERL_API_VERSION} is not set";
+ }
+
+ if ($CGI::Q) {
+ die "CGI.pm globals were not reset";
+ }
+
+ unless ($CGI::MOD_PERL) {
+ die "CGI.pm does not think this is mod_perl";
+ }
+
+ my $cgi = CGI->new;
+
+ my $param = $cgi->param('PARAM');
+ my $httpupload = $cgi->param('HTTPUPLOAD');
+
+ print $cgi->header('-type' => 'text/test-output',
+ '-X-Perl-Module' => __PACKAGE__);
+
+ if ($httpupload) {
+ no strict;
+ local $/;
+ my $content = <$httpupload>;
+ print "ok $content";
+ }
+ elsif ($param) {
+ print "ok $param";
+ }
+ else {
+ print "no param or upload data\n";
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlOptions -SetupEnv
diff --git a/2_0_13/t/response/TestModules/cgi2.pm b/2_0_13/t/response/TestModules/cgi2.pm
new file mode 100644
index 0000000..8d87638
--- /dev/null
+++ b/2_0_13/t/response/TestModules/cgi2.pm
@@ -0,0 +1,59 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::cgi2;
+
+# this handler doesn't use the :Apache layer, so CGI.pm needs to do
+# $r->read(...) instead of read(STDIN,...)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use CGI ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ unless ($ENV{MOD_PERL}) {
+ die "\$ENV{MOD_PERL} is not set";
+ }
+
+ unless ($ENV{MOD_PERL_API_VERSION} == 2) {
+ die "\$ENV{MOD_PERL_API_VERSION} is not set";
+ }
+
+ if ($CGI::Q) {
+ die "CGI.pm globals were not reset";
+ }
+
+ unless ($CGI::MOD_PERL) {
+ die "CGI.pm does not think this is mod_perl";
+ }
+
+ my $cgi = CGI->new($r);
+
+ my $param = $cgi->param('PARAM');
+ my $httpupload = $cgi->param('HTTPUPLOAD');
+
+ $r->print($cgi->header('-type' => 'text/test-output',
+ '-X-Perl-Module' => __PACKAGE__));
+
+ if ($httpupload) {
+ no strict;
+ local $/;
+ my $content = <$httpupload>;
+ $r->print("ok $content");
+ }
+ elsif ($param) {
+ $r->print("ok $param");
+ }
+ else {
+ $r->print("no param or upload data\n");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+
diff --git a/2_0_13/t/response/TestModules/cgipost.pm b/2_0_13/t/response/TestModules/cgipost.pm
new file mode 100644
index 0000000..48c0820
--- /dev/null
+++ b/2_0_13/t/response/TestModules/cgipost.pm
@@ -0,0 +1,26 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::cgipost;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use CGI ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ my $cgi = CGI->new;
+
+ print join ":", map { $cgi->param($_) } $cgi->param;
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestModules/cgipost2.pm b/2_0_13/t/response/TestModules/cgipost2.pm
new file mode 100644
index 0000000..57dc9fe
--- /dev/null
+++ b/2_0_13/t/response/TestModules/cgipost2.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::cgipost2;
+
+# this handler doesn't use the :Apache layer, so CGI.pm needs to do
+# $r->read(...) instead of read(STDIN,...)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use CGI ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ my $cgi = CGI->new($r);
+
+ $r->print(join ":", map { $cgi->param($_) } $cgi->param);
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+
diff --git a/2_0_13/t/response/TestModules/cgiupload.pm b/2_0_13/t/response/TestModules/cgiupload.pm
new file mode 100644
index 0000000..7952268
--- /dev/null
+++ b/2_0_13/t/response/TestModules/cgiupload.pm
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::cgiupload;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use CGI ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $cgi = CGI->new;
+
+ my $file = $cgi->param('filename');
+
+ while (<$file>) {
+ print;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+SetHandler perl-script
+PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestModules/cgiupload2.pm b/2_0_13/t/response/TestModules/cgiupload2.pm
new file mode 100644
index 0000000..3c4a522
--- /dev/null
+++ b/2_0_13/t/response/TestModules/cgiupload2.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::cgiupload2;
+
+# this handler doesn't use the :Apache layer, so CGI.pm needs to do
+# $r->read(...) instead of read(STDIN,...)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::compat ();
+use CGI ();
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ my $cgi = CGI->new($r);
+
+ local $\;
+ local $/;
+ my $file = $cgi->param('filename');
+ $r->print(<$file>);
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestModules/include_subreq.pm b/2_0_13/t/response/TestModules/include_subreq.pm
new file mode 100644
index 0000000..cf2bc2c
--- /dev/null
+++ b/2_0_13/t/response/TestModules/include_subreq.pm
@@ -0,0 +1,78 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::include_subreq;
+
+# this test calls a simple response handler, whose output includes a
+# simple SSI directive, processed by the INCLUDES output filter, which
+# triggers another response handler, which again returns an SSI
+# directive, again processed by INCLUDES, which again calls a response
+# handler
+#
+# main
+# resp => INCLUDES => => client
+# => 1st =>
+# subreq => INCLUDES => =>
+# response => =>
+# => 2nd =>
+# subreq =>
+# response
+#
+#
+#
+# here we test whether :Apache perlio (STDOUT) is reentrant, since the test
+# overrides STDOUT 3 times, recursively.
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ my $path_info = $r->path_info || '';
+ my $uri = $r->uri;
+
+ debug "uri: $uri, path_info: $path_info";
+
+ if ($path_info eq '/one') {
+ $uri =~ s/one/two/;
+ print qq[subreq <!--#include virtual="$uri" -->ok];
+ }
+ elsif ($path_info eq '/two') {
+ $uri = "/TestModules__include_subreq_dup/three";
+ #$uri =~ s/two/three/;
+ print qq[is <!--#include virtual="$uri" -->];
+ #print "is";
+ }
+ elsif ($path_info eq '/three') {
+ print "quite ";
+ }
+ else {
+ die "something is wrong, didn't get path_info";
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+# notice that perl-script is used on purpose here - testing whether
+# :Apache perlio is reentrant (SetHandler modperl doesn't go through
+# :Apache perlio layer)
+SetHandler perl-script
+PerlSetOutputFilter INCLUDES
+Options +IncludesNoExec
+<Base>
+# it's silly that we have to duplicate the resource, but mod_include
+# otherwise thinks we have a recursive call loop
+<Location /TestModules__include_subreq_dup>
+ PerlSetOutputFilter INCLUDES
+ Options +IncludesNoExec
+ SetHandler perl-script
+ PerlResponseHandler TestModules::include_subreq
+</Location>
+</Base>
diff --git a/2_0_13/t/response/TestModules/proxy.pm b/2_0_13/t/response/TestModules/proxy.pm
new file mode 100644
index 0000000..178ce69
--- /dev/null
+++ b/2_0_13/t/response/TestModules/proxy.pm
@@ -0,0 +1,77 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestModules::proxy;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+use Apache2::ServerRec ();
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+
+my $uri_real = "/TestModules__proxy_real";
+
+use Apache2::Const -compile => qw(DECLINED OK PROXYREQ_REVERSE);
+
+sub proxy {
+ my $r = shift;
+
+ return Apache2::Const::DECLINED if $r->proxyreq;
+ return Apache2::Const::DECLINED unless $r->uri eq '/TestModules__proxy';
+
+ my $s = $r->server;
+ my $real_url = sprintf "http://%s:%d%s",
+ $s->server_hostname, $s->port, $uri_real;
+
+ $r->proxyreq(Apache2::Const::PROXYREQ_REVERSE);
+ $r->uri($real_url);
+ $r->filename("proxy:$real_url");
+ $r->handler('proxy-server');
+
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+ $r->print("ok");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+ <VirtualHost TestModules::proxy>
+ <IfModule mod_proxy.c>
+ <Proxy http://@servername@:@port@/*>
+ <IfModule mod_version.c>
+ <IfVersion < 2.3.0>
+ <IfModule @ACCESS_MODULE@>
+ Order Deny,Allow
+ Deny from all
+ Allow from @servername@
+ </IfModule>
+ </IfVersion>
+ <IfVersion > 2.4.1>
+ <IfModule mod_access_compat.c>
+ Order Deny,Allow
+ Deny from all
+ Allow from @servername@
+ </IfModule>
+ </IfVersion>
+ </IfModule>
+ </Proxy>
+
+ PerlModule TestModules::proxy
+ PerlTransHandler TestModules::proxy::proxy
+ <Location /TestModules__proxy_real>
+ SetHandler modperl
+ PerlResponseHandler TestModules::proxy::response
+ </Location>
+ </IfModule>
+ </VirtualHost>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/response/TestPerl/api.pm b/2_0_13/t/response/TestPerl/api.pm
new file mode 100644
index 0000000..c034f08
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/api.pm
@@ -0,0 +1,54 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::api;
+
+# some perl APIs that we need to test that they work alright under mod_perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::Build;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ # - XXX: with perl 5.6.1 this test works fine on its own, but if
+ # run in the same interpreter after a test that involves a complex die
+ # call, as in the case of t/filter/in_error, which dies inside a
+ # filter, perl gets messed up here. this can be reproduced by
+ # running:
+ # t/TEST -maxclients 1 t/filter/in_error.t t/perl/api.t
+ # so skip that test for now on 5.6
+ #
+ # - win32 is an unrelated issue
+ plan $r, tests => 2,
+ need { "getppid() is not implemented on Win32"
+ => !Apache2::Build::WIN32(),
+ "getppid() is having problems with perl 5.6"
+ => !($] < 5.008),
+ };
+
+ {
+ # 5.8.1 w/ ithreads has a bug where it caches ppid in PL_ppid,
+ # but updates the record only if perl's fork is called, which
+ # is not the case with mod_perl. This results in getppid()
+ # returning 1. A local workaround in the mod_perl source at
+ # the child_init phase fixes the problem.
+ my $ppid = getppid();
+ t_debug "ppid $ppid";
+ ok $ppid > 1;
+
+ # verify that $pid != $ppid
+ t_debug "pid $$";
+ ok $ppid != $$;
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestPerl/hash_attack.pm b/2_0_13/t/response/TestPerl/hash_attack.pm
new file mode 100644
index 0000000..e76b432
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/hash_attack.pm
@@ -0,0 +1,187 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::hash_attack;
+
+# if the rehashing of the keys in the stash happens due to the hash attack,
+# mod_perl must not fail to find the previously cached stash entry (response
+# and fixup handlers in this test). Moreover it must not fail to find
+# that entry on the subsequent requests.
+#
+# the hash attack is detected when HV_MAX_LENGTH_BEFORE_REHASH keys find
+# themselves in the same hash bucket on splitting (which happens when the
+# number of keys crosses the threshold of a power of 2), in which case
+# starting from 5.8.2 the hash will rehash all its keys using a random hash
+# seed (PL_new_hash_seed, set in mod_perl or via PERL_HASH_SEED environment
+# variable)
+#
+# Prior to the attack condition hashes use the PL_hash_seed, which is
+# always 0.
+#
+# only in 5.8.1 hashes always use a non-zero PL_hash_seed (unless set
+# to 0 via PERL_HASH_SEED environment variable or compiled without
+# -DUSE_HASH_SEED or -DUSE_HASH_SEED_EXPLICIT
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestTrace;
+
+use Apache2::Const -compile => 'OK';
+
+use Math::BigInt;
+
+use constant MASK_U32 => 2**32;
+use constant HASH_SEED => 0; # 5.8.2: always zero before the rehashing
+use constant THRESHOLD => 14; #define HV_MAX_LENGTH_BEFORE_(SPLIT|REHASH)
+use constant START => "a";
+
+# create conditions which will trigger a rehash on the current stash
+# (__PACKAGE__::). Relevant for perl 5.8.2 and higher.
+sub init {
+ my $r = shift;
+
+ no strict 'refs';
+ my @attack_keys = attack(\%{__PACKAGE__ . "::"}) if $] >= 5.008002;
+
+ # define a new symbol (sub) after the attack has caused a re-hash
+ # check that mod_perl finds that symbol (fixup2) in the stash
+ no warnings 'redefine';
+ eval qq[sub fixup2 { return Apache2::Const::OK; }];
+ $r->push_handlers(PerlFixupHandler => \&fixup2);
+
+ return Apache2::Const::DECLINED;
+}
+
+sub fixup { return Apache2::Const::OK; }
+
+sub handler {
+ my $r = shift;
+ $r->print("ok");
+ return Apache2::Const::OK;
+}
+
+sub buckets { scalar(%{$_[0]}) =~ m#/([0-9]+)\z# ? 0+$1 : 8 }
+
+sub attack {
+ my $stash = shift;
+
+ #require Hash::Util; # avail since 5.8.0
+ debug "starting attack (it may take a long time!)";
+
+ my @keys;
+
+ # the minimum of bits required to mount the attack on a hash
+ my $min_bits = log(THRESHOLD)/log(2);
+
+ # if the hash has already been populated with a significant amount
+ # of entries the number of mask bits can be higher
+ my $keys = scalar keys %$stash;
+ my $bits = $keys ? log($keys)/log(2) : 0;
+ $bits = $min_bits if $min_bits > $bits;
+
+ $bits = ceil($bits);
+ # need to add 3 bits to cover the internal split cases
+ $bits += 3;
+ my $mask = 2**$bits-1;
+ debug "mask: $mask ($bits)";
+
+ my $s = START;
+ my $c = 0;
+ # get 2 keys on top of the THRESHOLD
+ my $h;
+ while (@keys < THRESHOLD+2) {
+ next if exists $stash->{$s};
+ $h = hash($s);
+ next unless ($h & $mask) == 0;
+ $c++;
+ $stash->{$s}++;
+ debug sprintf "%2d: %5s, %08x %s", $c, $s, $h, scalar(%$stash);
+ push @keys, $s;
+ debug "The hash collision attack has been successful"
+ if Internals::HvREHASH(%$stash);
+ } continue {
+ $s++;
+ }
+
+ # If the rehash hasn't been triggered yet, it's being delayed until the
+ # next bucket split. Add keys until a split occurs.
+ unless (Internals::HvREHASH(%$stash)) {
+ debug "Will add padding keys until hash split";
+ my $old_buckets = buckets($stash);
+ while (buckets($stash) == $old_buckets) {
+ next if exists $stash->{$s};
+ $h = hash($s);
+ $c++;
+ $stash->{$s}++;
+ debug sprintf "%2d: %5s, %08x %s", $c, $s, $h, scalar(%$stash);
+ push @keys, $s;
+ debug "The hash collision attack has been successful"
+ if Internals::HvREHASH(%$stash);
+ $s++;
+ }
+ }
+
+ # this verifies that the attack was mounted successfully. If
+ # HvREHASH is on it is. Otherwise the sequence wasn't successful.
+ die "Failed to mount the hash collision attack"
+ unless Internals::HvREHASH(%$stash);
+
+ debug "ending attack";
+
+ return @keys;
+}
+
+# least integer >= n
+sub ceil {
+ my $value = shift;
+ return int($value) < $value ? int($value) + 1 : int($value);
+}
+
+# trying to provide the fastest equivalent of C macro's PERL_HASH in
+# Perl - the main complication is that the C macro uses U32 integer
+# (unsigned int), which we can't do it Perl (it can do I32, with 'use
+# integer'). So we outsmart Perl and take modules 2*32 after each
+# calculation, emulating overflows that happen in C.
+sub hash {
+ my $s = shift;
+ my @c = split //, $s;
+ my $u = HASH_SEED;
+ for (@c) {
+ # (A % M) + (B % M) == (A + B) % M
+ # This works because '+' produces a NV, which is big enough to hold
+ # the intermidiate result. We only need the % before any "^" and "&"
+ # to get the result in the range for an I32.
+ # and << doesn't work on NV, so using 1 << 10
+ $u += ord;
+ $u += $u * (1 << 10); $u %= MASK_U32;
+ $u ^= $u >> 6;
+ }
+ $u += $u << 3; $u %= MASK_U32;
+ $u ^= $u >> 11; $u %= MASK_U32;
+ $u += $u << 15; $u %= MASK_U32;
+ $u;
+}
+
+# a bit slower but simpler version
+sub hash_original {
+ my $s = shift;
+ my @c = split //, $s;
+ my $u = HASH_SEED;
+ for (@c) {
+ $u += ord; $u %= MASK_U32;
+ $u += $u << 10; $u %= MASK_U32;
+ $u ^= $u >> 6; $u %= MASK_U32;
+ }
+ $u += $u << 3; $u %= MASK_U32;
+ $u ^= $u >> 11; $u %= MASK_U32;
+ $u += $u << 15; $u %= MASK_U32;
+ $u;
+}
+
+1;
+
+__END__
+PerlModule TestPerl::hash_attack
+PerlInitHandler TestPerl::hash_attack::init
+# call twice to verify an access to the same hash value after the rehash
+PerlFixupHandler TestPerl::hash_attack::fixup TestPerl::hash_attack::fixup
+
diff --git a/2_0_13/t/response/TestPerl/ithreads.pm b/2_0_13/t/response/TestPerl/ithreads.pm
new file mode 100644
index 0000000..84f11f6
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/ithreads.pm
@@ -0,0 +1,103 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::ithreads;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestTrace;
+
+use Apache2::Const -compile => 'OK';
+
+# XXX: at this moment ithreads can be used only with 5.8.1. However
+# once ithreads will be available on CPAN, we will need to change the
+# check for perl 5.8.0 and this certain version of ithreads (here and
+# in t/conf/post_config_startup.pl
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 4, need
+ need_threads,
+ {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)};
+
+ # threads must have been preloaded at the server startup for this
+ # test (this is done at t/conf/post_config_startup.pl)
+ require threads;
+ threads->import();
+
+ # sky: the more modules are loaded, the slower new ithreads start
+ # because more things need to be cloned
+ debug '%INC size: ' . scalar(keys %INC) . "\n";
+
+ {
+ my $tid = threads->self->tid;
+ debug "1st TID is $tid" if defined $tid;
+ ok defined $tid;
+ }
+
+ {
+ my $thr = threads->new(sub {
+ my $tid = threads->self->tid;
+ debug "2nd TID is $tid" if defined $tid;
+ return 2;
+ });
+ ok t_cmp($thr->join, 2, "thread callback returned value");
+ }
+
+ {
+ require threads::shared;
+ my $counter_priv = 1;
+ my $counter_shar : shared = 1;
+
+ my $thr = threads->new(sub {
+ my $tid = threads->self->tid;
+ debug "2nd TID is $tid" if defined $tid;
+ $counter_priv += $counter_priv for 1..10;
+ {
+ lock $counter_shar;
+ $counter_shar += $counter_shar for 1..10;
+ }
+ });
+
+ $counter_priv += $counter_priv for 1..10;
+ {
+ lock $counter_shar;
+ $counter_shar += $counter_shar for 1..10;
+ }
+
+ $thr->join;
+ ok t_cmp($counter_shar, 2**20, "shared counter");
+ ok t_cmp($counter_priv, 2**10, "private counter");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+
+__END__
+# APACHE_TEST_CONFIG_ORDER 941
+
+<VirtualHost TestPerl::ithreads>
+
+ <IfDefine PERL_USEITHREADS>
+ # a new interpreter pool
+ PerlOptions +Parent
+ PerlInterpStart 1
+ PerlInterpMax 1
+ PerlInterpMinSpare 1
+ PerlInterpMaxSpare 1
+ </IfDefine>
+
+ # use test system's @INC
+ PerlSwitches -I@serverroot@
+ PerlRequire "conf/modperl_inc.pl"
+
+ <Location /TestPerl__ithreads>
+ SetHandler modperl
+ PerlResponseHandler TestPerl::ithreads
+ </Location>
+
+</VirtualHost>
diff --git a/2_0_13/t/response/TestPerl/ithreads3.pm b/2_0_13/t/response/TestPerl/ithreads3.pm
new file mode 100644
index 0000000..3edae5e
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/ithreads3.pm
@@ -0,0 +1,109 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::ithreads3;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec;
+use Apache2::RequestIO;
+use Apache2::RequestUtil;
+use APR::Pool;
+use Apache2::Const -compile => 'OK', 'DECLINED';
+
+# XXX: These tests rely on the assumption that the virtual host is not
+# otherwise accessed. In this case the same interpreter is chosen
+# for each phase. The $counter counts them.
+# Of course if only 1 interp is configured it must be hit each time.
+
+my $counter=0;
+
+sub response {
+ my $r=shift;
+ $r->content_type('text/plain');
+ $r->print($counter);
+ return Apache2::Const::OK;
+}
+
+sub count { $counter++; return Apache2::Const::DECLINED; }
+
+sub clear_pool {
+ delete $_[0]->pnotes->{my_pool};
+ return Apache2::Const::DECLINED;
+}
+
+sub trans {
+ my $r=shift;
+ my $test=$r->args;
+ $counter=0;
+ if( $test eq '1' ) {
+ # this is to check for a bug in modperl_response_handler versus
+ # modperl_response_handler_cgi. The former used to allocate an
+ # extra interpreter for its work. In both cases $counter should be
+ # 2 in the response phase
+ $r->push_handlers( PerlMapToStorageHandler=>__PACKAGE__.'::count' );
+ $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::count' );
+ }
+ elsif( $test eq '2' ) {
+ # now add an extra PerlCleanupHandler. It is run each time the
+ # interp is released. So it is run after Trans, MapToStorage and
+ # Fixup. In the response phase $counter should be 5. After Response
+ # it is run again but that is after.
+ # This used to eat up all interpreters because modperl_interp_unselect
+ # calls modperl_config_request_cleanup that allocates a new interp
+ # to handle the cleanup. When this interp is then unselected
+ # modperl_interp_unselect gets called again but the cleanup handler is
+ # still installed. So the cycle starts again until all interpreters
+ # are in use or the stack runs out. Then the thread is locked infinitely
+ # or a segfault appears.
+ $r->push_handlers( PerlMapToStorageHandler=>__PACKAGE__.'::count' );
+ $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::count' );
+ $r->push_handlers( PerlCleanupHandler=>__PACKAGE__.'::count' );
+ }
+ elsif( $test eq '3' ) {
+ # a subpool adds an extra reference to the interp. So it is preserved
+ # and bound to the request until the pool is destroyed. So the cleanup
+ # handler is run only once after Fixup. Hence the counter is 3.
+ $r->push_handlers( PerlMapToStorageHandler=>__PACKAGE__.'::count' );
+ $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::count' );
+ $r->push_handlers( PerlCleanupHandler=>__PACKAGE__.'::count' );
+ $r->pnotes->{my_pool}=$r->pool->new;
+ $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::clear_pool' );
+ }
+ return Apache2::Const::DECLINED;
+}
+
+1;
+
+__END__
+# APACHE_TEST_CONFIG_ORDER 942
+
+<VirtualHost TestPerl::ithreads3>
+
+ <IfDefine PERL_USEITHREADS>
+ # a new interpreter pool
+ PerlOptions +Parent
+ PerlInterpStart 3
+ PerlInterpMax 3
+ PerlInterpMinSpare 1
+ PerlInterpMaxSpare 3
+ # PerlInterpScope handler
+ </IfDefine>
+
+ # use test system's @INC
+ PerlSwitches -I@serverroot@
+ PerlRequire "conf/modperl_inc.pl"
+ PerlModule TestPerl::ithreads3
+
+ <Location /modperl>
+ SetHandler modperl
+ PerlResponseHandler TestPerl::ithreads3::response
+ </Location>
+
+ <Location /perl-script>
+ SetHandler perl-script
+ PerlResponseHandler TestPerl::ithreads3::response
+ </Location>
+
+ PerlTransHandler TestPerl::ithreads3::trans
+
+</VirtualHost>
diff --git a/2_0_13/t/response/TestPerl/ithreads_args.pm b/2_0_13/t/response/TestPerl/ithreads_args.pm
new file mode 100644
index 0000000..b3e6eb8
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/ithreads_args.pm
@@ -0,0 +1,33 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::ithreads_args;
+
+# reproducing a bug in perl ithreads: [perl #34342]
+# https://rt.perl.org/rt3/Ticket/Display.html?id=34342
+#
+# here an unshifted $r (i.e. as it leaves @_ populated causes a scalar
+# leak in the thread).
+
+use Devel::Peek;
+use Apache::Test;
+
+sub handler { # XXX: unshifted $_[0] leaks scalar
+ #Dump $_[0];
+ #my $r = shift; # shift removes the leak
+ my $r = $_[0];
+ #Dump $r; # here PADBUSY,PADMY prevent the ithread from cloning it
+
+ plan $r, tests => 1, need
+ need_threads,
+ {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)};
+
+ require threads;
+
+ warn "\n*** The following leak is expected (perl bug #34342) ***\n";
+ threads->new(sub {})->join;
+
+ ok 1;
+
+ return 0;
+}
+
+1;
diff --git a/2_0_13/t/response/TestPerl/ithreads_eval.pm b/2_0_13/t/response/TestPerl/ithreads_eval.pm
new file mode 100644
index 0000000..fe1b0af
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/ithreads_eval.pm
@@ -0,0 +1,51 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::ithreads_eval;
+
+# reproducing a bug in perl ithreads: [perl #34341]
+# https://rt.perl.org/rt3/Ticket/Display.html?id=34341
+#
+# $thr->join triggers the following leak:
+# - due to to local $0, (its second MAGIC's MG_OBJ,
+# you can see it in the output of Dump $0). This leak was first
+# spotted in the RegistryCooker.pm which localizes $0
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Devel::Peek;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1, need
+ need_threads,
+ {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)};
+
+ require threads;
+
+ eval <<'EOI';
+sub mytest {
+ local $0 = 'mememe'; # <== XXX: leaks scalar
+ my $thr;
+ $thr = threads->new(\&mythread);
+ $thr->join; # <== XXX: triggers scalar leak
+}
+sub mythread {
+ #Dump $0;
+}
+EOI
+
+ warn "\n*** The following leak is expected (perl bug #34341) ***\n";
+ mytest();
+
+ ok 1;
+
+ return Apache2::Const::OK;
+}
+
+1;
diff --git a/2_0_13/t/response/TestPerl/signals.pm b/2_0_13/t/response/TestPerl/signals.pm
new file mode 100644
index 0000000..2c08d43
--- /dev/null
+++ b/2_0_13/t/response/TestPerl/signals.pm
@@ -0,0 +1,86 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestPerl::signals;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache2::BuildConfig;
+use Apache::TestConfig;
+
+use Apache2::MPM ();
+
+use POSIX qw(SIGALRM);
+
+use constant OSX => Apache::TestConfig::OSX;
+
+use Apache2::Const -compile => qw(OK);
+
+my $mpm = lc Apache2::MPM->show;
+
+# signal handlers don't work anywhere but with prefork, since signals
+# and threads don't mix
+# moreover "unsafe"-non-POSIX sighandlers don't work under static prefork
+
+sub handler {
+ my $r = shift;
+
+ my $build = Apache2::BuildConfig->new;
+ my $static = $build->should_build_apache ? 1 : 0;
+
+ my $tests = $static ? 1 : 2;
+
+ plan $r, tests => $tests,
+ need { "works only for prefork" => ($mpm eq 'prefork') };
+
+ # doesn't work under static prefork
+ if (!$static) {
+ if (OSX) {
+ skip "ALRM can't be used on darwin", 0;
+ }
+ else {
+ local $ENV{PERL_SIGNALS} = "unsafe";
+
+ eval {
+ local $SIG{ALRM} = sub { die "alarm" };
+ alarm 2;
+ run_for_5_sec();
+ alarm 0;
+ };
+ ok t_cmp $@, qr/alarm/, "SIGALRM / unsafe %SIG";
+ }
+ }
+
+ # POSIX::sigaction doesn't work under 5.6.x
+ if ($] >= 5.008) {
+ my $mask = POSIX::SigSet->new( SIGALRM );
+ my $action = POSIX::SigAction->new(sub { die "alarm" }, $mask);
+ my $oldaction = POSIX::SigAction->new();
+ POSIX::sigaction(SIGALRM, $action, $oldaction );
+ eval {
+ alarm 2;
+ run_for_5_sec();
+ alarm 0;
+ };
+ POSIX::sigaction(SIGALRM, $oldaction); # restore original
+
+ ok t_cmp $@, qr/alarm/, "SIGALRM / POSIX";
+ }
+ else {
+ skip "POSIX::sigaction doesn't work under 5.6.x", 0;
+ }
+
+ return Apache2::Const::OK;
+}
+
+sub run_for_5_sec {
+ for (1..20) { # ~5 sec
+ my $x = 3**20;
+ select undef, undef, undef, 0.25;
+ }
+}
+
+1;
+
+__END__
diff --git a/2_0_13/t/response/TestUser/rewrite.pm b/2_0_13/t/response/TestUser/rewrite.pm
new file mode 100644
index 0000000..0416612
--- /dev/null
+++ b/2_0_13/t/response/TestUser/rewrite.pm
@@ -0,0 +1,76 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestUser::rewrite;
+
+# test here the technique of rewriting the URI namespace and
+# pushing/changing the query string (args). Note that in this test we
+# use a custom maptostorage handler so Apache won't complain that we
+# didn't set r->filename in the core maptostorage handler. the custom
+# handler simply shortcuts that phase, with the added benefit of
+# skipping the ap_directory_walk's stat() calls which speeds up the
+# whole thing.
+#
+# an alternative solution is to return Apache2::Const::DECLINED from the trans
+# handler, in which case map2storage is not required (but it'll do a
+# bunch of stat() calls then, which you may want to avoid)
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestRec ();
+use Apache2::RequestIO ();
+use Apache2::URI ();
+
+use Apache2::Const -compile => qw(DECLINED OK);
+
+my $uri_real = "/TestUser__rewrite_real";
+my $args_real = "foo=bar&boo=tar";
+
+sub trans {
+ my $r = shift;
+
+ return Apache2::Const::DECLINED unless $r->uri eq '/TestUser__rewrite';
+
+ $r->uri($uri_real);
+ $r->args($args_real);
+
+ return Apache2::Const::OK;
+}
+
+sub map2storage {
+ my $r = shift;
+
+ return Apache2::Const::DECLINED unless $r->uri eq $uri_real;
+
+ # skip ap_directory_walk stat() calls
+ return Apache2::Const::OK;
+}
+
+sub response {
+ my $r = shift;
+
+ plan $r, tests => 1;
+
+ my $args = $r->args();
+
+ ok t_cmp($args, $args_real, "args");
+
+ return Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+ <VirtualHost TestUser::rewrite>
+ PerlModule TestUser::rewrite
+ PerlTransHandler TestUser::rewrite::trans
+ PerlMapToStorageHandler TestUser::rewrite::map2storage
+ <Location /TestUser__rewrite_real>
+ SetHandler modperl
+ PerlResponseHandler TestUser::rewrite::response
+ </Location>
+ </VirtualHost>
+</NoAutoConfig>
+
diff --git a/2_0_13/t/response/TestVhost/config.pm b/2_0_13/t/response/TestVhost/config.pm
new file mode 100644
index 0000000..4a581b6
--- /dev/null
+++ b/2_0_13/t/response/TestVhost/config.pm
@@ -0,0 +1,72 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestVhost::config;
+
+# Test whether under threaded mpms (and not) a vhost with 'PerlOptions
+# +Parent', can run <Perl> sections, which call into config again via
+# add_config().
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::RequestUtil ();
+use APR::Table ();
+
+use File::Spec::Functions qw(canonpath catdir);
+
+use Apache2::Const -compile => 'OK';
+
+# initialized in t/htdocs/vhost/post_config.pl
+our $restart_count;
+
+# using a different from 'handler' name on purpose, to make sure
+# that the module is preloaded at the server startup
+sub my_handler {
+ my $r = shift;
+
+ plan $r, tests => 2;
+
+ {
+ my $expected = $r->document_root;
+ my $received = $r->dir_config->get('DocumentRootCheck');
+ ok t_cmp(canonpath($received), canonpath($expected), "DocumentRoot");
+ }
+
+ {
+ ok t_cmp($restart_count, 2, "PerlPostConfigRequire");
+ }
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestVhost::config>
+ DocumentRoot @documentroot@/vhost
+
+ <IfDefine PERL_USEITHREADS>
+ # a new interpreter pool
+ PerlOptions +Parent
+ PerlInterpStart 1
+ PerlInterpMax 1
+ PerlInterpMinSpare 1
+ PerlInterpMaxSpare 1
+ </IfDefine>
+
+ # use test system's @INC
+ PerlSwitches -I@serverroot@
+
+ # mp2 modules
+ PerlRequire "@serverroot@/conf/modperl_inc.pl"
+
+ # private to this vhost stuff
+ PerlRequire "@documentroot@/vhost/startup.pl"
+ PerlPostConfigRequire "@documentroot@/vhost/post_config.pl"
+
+ # <Location /TestVhost__config> container is added via add_config
+ # in t/htdocs/vhost/startup.pl
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/response/TestVhost/log.pm b/2_0_13/t/response/TestVhost/log.pm
new file mode 100644
index 0000000..2bbf438
--- /dev/null
+++ b/2_0_13/t/response/TestVhost/log.pm
@@ -0,0 +1,99 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package TestVhost::log;
+
+# testing that the warn and other logging functions are writing into
+# the vhost error_log and not the main one.
+
+use strict;
+use warnings;
+# don't use:
+# use warnings FATAL => 'all';
+# here as it breaks the $SIG{__WARN__} sub test for perl 5.6, though
+# it works fine with perl 5.8+
+
+use Apache2::RequestUtil ();
+use Apache2::Log ();
+use Apache2::ServerRec qw(warn); # override warn locally
+
+use File::Spec::Functions qw(catfile);
+
+use Apache::Test;
+use Apache::TestUtil;
+use TestCommon::LogDiff;
+
+use Apache2::Const -compile => 'OK';
+
+my @methods1 = (
+ '$r->log->warn',
+ '$r->log_error',
+ '$r->warn',
+ '$s->log->warn',
+ '$s->log_error',
+ '$s->warn',
+);
+
+my @methods2 = (
+ 'Apache2::ServerRec::warn',
+ 'warn',
+);
+
+my $path = catfile Apache::Test::vars('documentroot'),
+ qw(vhost error_log);
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 1 + @methods1 + @methods2;
+
+ my $s = $r->server;
+ my $logdiff = TestCommon::LogDiff->new($path);
+
+ ### $r|$s logging
+ for my $m (@methods1) {
+ eval "$m(q[$m])";
+ ok t_cmp $logdiff->diff, qr/\Q$m/, $m;
+ }
+
+ ### object-less logging
+ # set Apache2::RequestUtil->request($r) instead of using
+ # PerlOptions +GlobalRequest
+ # in order to make sure that the above tests work fine,
+ # w/o having the global request set
+ Apache2::RequestUtil->request($r);
+ for my $m (@methods2) {
+ eval "$m(q[$m])";
+ ok t_cmp $logdiff->diff, qr/\Q$m/, $m;
+ }
+
+ # internal warnings (also needs +GlobalRequest)
+ {
+ no warnings; # avoid FATAL warnings
+ use warnings;
+ local $SIG{__WARN__} = \&Apache2::ServerRec::warn;
+ eval q[my $x = "aaa" + 1;];
+ ok t_cmp
+ $logdiff->diff,
+ qr/Argument "aaa" isn't numeric in addition/,
+ "internal warning";
+ }
+
+ # die logs into the vhost log just fine
+ #die "horrible death!";
+
+ Apache2::Const::OK;
+}
+
+1;
+__END__
+<NoAutoConfig>
+<VirtualHost TestVhost::log>
+ DocumentRoot @documentroot@/vhost
+ ErrorLog @documentroot@/vhost/error_log
+
+ <Location /TestVhost__log>
+ SetHandler modperl
+ PerlResponseHandler TestVhost::log
+ </Location>
+
+</VirtualHost>
+</NoAutoConfig>
diff --git a/2_0_13/t/user/README b/2_0_13/t/user/README
new file mode 100644
index 0000000..7e2e782
--- /dev/null
+++ b/2_0_13/t/user/README
@@ -0,0 +1,2 @@
+This directory contains userspace tests, such as those that excercise
+non-unit, multiple-API tests, or Apache integration tests, etc.
diff --git a/2_0_13/t/user/rewrite.t b/2_0_13/t/user/rewrite.t
new file mode 100644
index 0000000..64afec6
--- /dev/null
+++ b/2_0_13/t/user/rewrite.t
@@ -0,0 +1,13 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestUser::rewrite';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/vhost/config.t b/2_0_13/t/vhost/config.t
new file mode 100644
index 0000000..36d1a49
--- /dev/null
+++ b/2_0_13/t/vhost/config.t
@@ -0,0 +1,29 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# the handler is configured in modperl_extra.pl via
+# Apache2::ServerUtil->server->add_config
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest 'GET';
+
+my $module = 'TestVhost::config';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+my $res = GET $url;
+
+if ($res->is_success) {
+ print $res->content;
+}
+else {
+ if ($res->code == 404) {
+ my $docroot = Apache::Test::vars('documentroot');
+ die "this test gets its <Location> configuration added via " .
+ "$docroot/vhost/startup.pl, this could be the cause " .
+ "of the failure";
+ }
+ else {
+ die "server side has failed (response code: ", $res->code, "),\n",
+ "see t/logs/error_log for more details\n";
+ }
+}
diff --git a/2_0_13/t/vhost/log.t b/2_0_13/t/vhost/log.t
new file mode 100644
index 0000000..3205905
--- /dev/null
+++ b/2_0_13/t/vhost/log.t
@@ -0,0 +1,10 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use Apache::TestUtil;
+use Apache::TestRequest 'GET_BODY_ASSERT';
+
+my $module = 'TestVhost::log';
+my $url = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+print GET_BODY_ASSERT $url;
+
diff --git a/2_0_13/todo/2.0.6 b/2_0_13/todo/2.0.6
new file mode 100644
index 0000000..d64c996
--- /dev/null
+++ b/2_0_13/todo/2.0.6
@@ -0,0 +1,10 @@
+SHOW STOPPERS
+====================
+- Windows Segfaults [needs windows developer owner, ]
+- MANIFEST verifications [needs detail, ]
+- rt.cpan.org PRs [pgollucci, phred, ]
+
+NICE TO HAVE
+=============
+- Smolder, https://issues.apache.org/jira/browse/INFRA-1612 [pgollucci, ]
+
diff --git a/2_0_13/todo/README b/2_0_13/todo/README
new file mode 100644
index 0000000..c87880d
--- /dev/null
+++ b/2_0_13/todo/README
@@ -0,0 +1,9 @@
+this directory contains notes on whats left to be done:
+
+release - showstopper issues for mod_perl 2.0 release
+
+features_* -
+
+bugs_* -
+
+docs - docs todo
diff --git a/2_0_13/todo/api_status b/2_0_13/todo/api_status
new file mode 100644
index 0000000..22fd6a6
--- /dev/null
+++ b/2_0_13/todo/api_status
@@ -0,0 +1,156 @@
+This file provides the status of the supported API, via the
+API documentation files.
+
+col1 legend
+-----------
+-: not started/unknown
++: in process
+V: done (for 2.0 release)
+g = gozer at work
+
+col2 legend
+-----------
+-: not started/unknown
+P: post 2.0 (has API to be polished after 2.0 release)
+V: done completely
+
+- the file path is relative to the modperl-docs cvs repository
+#########################################################
+VV src/docs/2.0/api/Apache.pod
+VV src/docs/2.0/api/Apache/Access.pod
+VP src/docs/2.0/api/Apache/CmdParms.pod
+ context
+VV src/docs/2.0/api/Apache/Command.pod
+VP src/docs/2.0/api/Apache/Connection.pod
+ conn_config
+VP src/docs/2.0/api/Apache/Const.pod
+ (this will never be complete, fill it in as we go)
+VV src/docs/2.0/api/Apache/Directive.pod
+VP src/docs/2.0/api/Apache/Filter.pod
+ The whole TIE interface
+VV src/docs/2.0/api/Apache/FilterRec.pod
+VV src/docs/2.0/api/Apache/HookRun.pod
+VP src/docs/2.0/api/Apache/Log.pod
+ log_pid
+VV src/docs/2.0/api/Apache/Module.pod
+VV src/docs/2.0/api/Apache/PerlSections.pod
+VV src/docs/2.0/api/Apache/Process.pod
+VV src/docs/2.0/api/Apache/Reload.pod
+VV src/docs/2.0/api/Apache/RequestIO.pod
+VP src/docs/2.0/api/Apache/RequestRec.pod
+ allowed_methods
+ allowed_xmethods
+ content_languages (was in mp1, need to implement APR::ArrayHeader )
+ request_config
+ used_path_info
+VV src/docs/2.0/api/Apache/RequestUtil.pod
+VP src/docs/2.0/api/Apache/Response.pod
+ send_error_response
+ send_mmap
+VP src/docs/2.0/api/Apache/ServerRec.pod
+ addrs
+ lookup_defaults
+ module_config
+ names
+ wild_names
+VP src/docs/2.0/api/Apache/ServerUtil.pod
+ error_log2stderr
+VV src/docs/2.0/api/Apache/SubProcess.pod
+VV src/docs/2.0/api/Apache/SubRequest.pod
+ internal_fast_redirect
+ lookup_dirent
+VV src/docs/2.0/api/Apache/URI.pod
+VV src/docs/2.0/api/Apache/Util.pod
+
+VV src/docs/2.0/api/ModPerl/Const.pod
+VV src/docs/2.0/api/ModPerl/Global.pod
+VV src/docs/2.0/api/ModPerl/Util.pod
+
+VV src/docs/2.0/api/APR.pod
+VV src/docs/2.0/api/APR/Base64.pod
+VV src/docs/2.0/api/APR/Brigade.pod
+VP src/docs/2.0/api/APR/Bucket.pod
+ data
+ start
+VV src/docs/2.0/api/APR/BucketAlloc.pod
+VV src/docs/2.0/api/APR/BucketType.pod
+VP src/docs/2.0/api/APR/Const.pod
+ (this will never be complete, fill it in as we go)
+VV src/docs/2.0/api/APR/Date.pod
+VV src/docs/2.0/api/APR/Error.pod
+VV src/docs/2.0/api/APR/Finfo.pod
+VV src/docs/2.0/api/APR/IpSubnet.pod
+VV src/docs/2.0/api/APR/OS.pod
++V src/docs/2.0/api/APR/PerlIO.pod
+ (convert to use exceptions)
+VP src/docs/2.0/api/APR/Pool.pod
+ cleanup_for_exec
+ (clean has some win32 problems)
+VP src/docs/2.0/api/APR/SockAddr.pod
+ equal
+VP src/docs/2.0/api/APR/Socket.pod
+ bind
+ close
+ connect
+ listen
+ recvfrom
+ sendto
+VV src/docs/2.0/api/APR/String.pod
+VV src/docs/2.0/api/APR/Table.pod
+VP src/docs/2.0/api/APR/ThreadMutex.pod
+ DESTROY
+ lock
+ new
+ pool_get
+ trylock
+ unlock
+VV src/docs/2.0/api/APR/URI.pod
+VP src/docs/2.0/api/APR/Util.pod
+ filepath_name_get
+ password_get
+VV src/docs/2.0/api/APR/UUID.pod
+
+#####################
+### other modules ###
+#####################
+
+VV src/docs/2.0/api/Apache/Status.pod
+VV src/docs/2.0/api/Apache/SizeLimit.pod
+VV src/docs/2.0/api/Apache/Resource.pod
+VV src/docs/2.0/api/Apache/compat.pod
+VV src/docs/2.0/api/Apache/porting.pod
+-- src/docs/2.0/api/ModPerl/BuildMM.pod
+-- src/docs/2.0/api/ModPerl/MM.pod
+VV src/docs/2.0/api/ModPerl/MethodLookup.pod
+-- src/docs/2.0/api/ModPerl/PerlRun.pod
+-- src/docs/2.0/api/ModPerl/Registry.pod
+-- src/docs/2.0/api/ModPerl/RegistryBB.pod
+-- src/docs/2.0/api/ModPerl/RegistryCooker.pod
+-- src/docs/2.0/api/ModPerl/RegistryLoader.pod
+
+
+################################
+### Other API related things ###
+################################
+
+* the following accessors might be turned into read/write (they are
+ readonly at the moment). if you think that should be the case,
+ please document the change and hopefully add a new sub-test.
+
+ conn_rec:
+ ---------
+ local_addr
+ remote_addr
+ remote_host
+ aborted
+ local_ip
+ local_host
+
+ ap_directive_t:
+ ---------------
+ next
+ first_child
+ parent
+ filename
+ line_num
+
diff --git a/2_0_13/todo/bugs_apr_ext b/2_0_13/todo/bugs_apr_ext
new file mode 100644
index 0000000..33ff108
--- /dev/null
+++ b/2_0_13/todo/bugs_apr_ext
@@ -0,0 +1,26 @@
+########################################
+# external (non-mod_perl) APR:: issues #
+########################################
+
+* As mike chamberlain told me over irc, apr-ext/perlio was faling for
+ him because of the modperl_perl_gensym not being resolved in
+ APR/PerlIO.so. I didn't see that error since on linux by default
+ symbols resolution is lazy and since that part of the api wasn't
+ tested I did see the problem. On MacOSX the loading is RTLD_NOW
+ (non-lazy) so it detects any missing symbols problems immediately.
+
+ Luckily DynaLoader allows us to force the non-lazy mode by setting
+ an env var: PERL_DL_NONLAZY=1. We need to force this env variable on
+ when building with MP_MAINTAINER=1. I suppose that it should be
+ added to the autogenerated t/TEST and t/SMOKE. and to
+ t/conf/modperl_extra.pl ($ENV{PERL_DL_NONLAZY}=1) so it affects the
+ server-side as well as the client-side (normally env var aren't
+ propogated to the server).
+
+* APR::Pool relies on interpreter management function:
+ modperl_interp_unselect. At the moment I've worked around it by
+ defining an empty function in APR.xs. But a cleaner solution is
+ desirable.
+
+* modules that we need to add tests for in apr-ext:
+ APR::IpSubnet
diff --git a/2_0_13/todo/bugs_build b/2_0_13/todo/bugs_build
new file mode 100644
index 0000000..9a1ca38
--- /dev/null
+++ b/2_0_13/todo/bugs_build
@@ -0,0 +1,85 @@
+#######################
+# Build/Startup Issue #
+#######################
+
+
+OS Ver Mod Comments
+----------------------------------------------------------------------
+OpenBSD 2.9 DSO Builds but won't start, with segfaults in the
+ Perl lexer. I wasn't even able to start mp1-dso with
+ the customly built perl (tried 5.6.1 .. 5.9.0)
+ -- the segfault is again in lexer. It seems that
+ the standard OpenBSD perl package has been heavily
+ patched, when the core system perl 5.6.0 package was
+ built, since I can run 'make test' on mp1-dso, but not
+ with a customly built 5.6.0 with the same
+ options. Since 2.9 is no longer supported by OpenBSD,
+ there is no 5.6.1 or higher to try, so at this moment
+ we simply give up on 2.9. We think that the static mp2
+ build should work just fine (once it's available).
+
+AIX 3.3 DSO Works with -berok to ignore linking errors (symbol
+ resolution). Should replace -berok with a proper
+ symbol resolution at linking time, but I had not much
+ success with using this approach (dlopen fails).
+
+AIX 4.3.3 DSO reported to work with mod_perl_1.99_12 and
+ Apache 2.0.48/prefork mpm
+ but doesn't start with worker:
+ http://marc.theaimsgroup.com/?t=106894906200003&r=1&w=2
+
+FreeBSD ?? DSO Works with non-threaded perl (4.8-RELEASE-5.2-RELEASE, 6.0-CURRENT)
+ http://marc.theaimsgroup.com/?l=apache-modperl&m=106399870822612&w=2
+ The following combo is known to work:
+ http://gossamer-threads.com/lists/modperl/modperl/82887
+ FreeBSD 5.4-RELEASE
+ gcc 3.4.2
+ perl 5.8.7 WITH ithreads
+ httpd 2.0.54 apr IS THREADED (worker mpm)
+ mod_perl2.0.1
+
+HPUX11i DSO
+ PA-RISC2.0-thread-multi-LP64
+ hp-ux loire b.11.11 u 9000800 1756907651 unlimited-user license
+ Cannot load .../modules/mod_perl.so into server: Error 0
+ http://marc.theaimsgroup.com/?t=108325310800002&r=1&w=2
+ Bill Rowe gives some hints here
+ http://marc.theaimsgroup.com/?l=apache-modperl&m=108334017416318&w=2
+ Static works OK!
+
+* Does not compile with bleedperl (5.9.x) due to modperl_error.c and Perl_croak()
+ on FreeBSD. This is a PERL bug, but p5p and myself, and not sure where the problem is yet.
+
+* gcc 4.x and higher compiles break under -Werror
+[pgollucci volunteers]
+
+* AAA changes in httpd break httpd 2.3.x+ (svn trunk) builds terribly on all platforms.
+
+* Need to cleanup functions only needed for certain build flavors
+ (perlio/threads/etc) out of lib/ModPerl/WrapXS.pm:$ithread_exports
+ and use the newer, simpler #ifdef technique (see modperl_io_apache_init
+ for an example)
+
+* we should stop generating xs/apache_*, at least for a reason that
+ it's incomplete and will be never complete as we don't keep up with
+ changes with ap_/apr_ namespace. Also we don't have the logic to
+ handle cases where functions aren't available on certain
+ platforms. Importing these unavailable functions may cause loading
+ problems on some platforms (aix?). If developers need to import
+ symbols from ap_/apr_ namespace they should use .exp files installed
+ by httpd/apr/aprutil.
+
+* we have a dependency check problem when xs/*/*.h use code from
+ xs/modperl_xs*.h, when the latter change 'make' won't rebuild the
+ dependant files
+
+* Testing:
+ Need to put Philippe's smoking test into the core
+ -- shouldn't forget to test with perlio enabled and disabled
+
+* source_scan won't create Wrap/Foo/Bar.xs if
+ xs/maps/modperl_functions.map defines only a boot section:
+ MODULE=APR::IO PACKAGE=APR::IO BOOT=1
+ unless there is at least one function added to the .map file
+ http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=100702825506778&w=2
+
diff --git a/2_0_13/todo/bugs_mp b/2_0_13/todo/bugs_mp
new file mode 100644
index 0000000..e0e9412
--- /dev/null
+++ b/2_0_13/todo/bugs_mp
@@ -0,0 +1,136 @@
+#################
+# mod_perl bugs #
+#################
+
+* local %ENV doesn't work, see t/modperl/local_ent.
+
+* PerlOptions None needs to be implemented, see t/modperl/perl_options2.t
+
+* PerlIOApache_flush()
+ Setting local $| = 0 doesn't work with regular print statements under ModPerl::*
+
+ http://p6m7g8.net/MP2/84625
+ http://www.gossamer-threads.com/lists/modperl/dev/85365
+ [pgollucci volunteers]
+
+* $r->rflush doesn't work. see:
+ http://marc.theaimsgroup.com/?l=apache-modperl&m=103847990813285&w=2
+ I also see a weird behavior where it does sends FLUSH buckets but
+ they all seem to fall through the data, thus not really flushing
+ anything. this can be easily reproduced with MyApache::FilterSnoop.
+
+ See also
+ http://www.gossamer-threads.com/lists/modperl/dev/84744?search_string=%23%7C%2C%20flushing%2C%20etc;#84743
+ for a related $| but not the same issue.
+ [pgollucci volunteers]
+
+* early pool destruction issues
+ http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=108872944815382&w=2
+
+* PassEnv/SetEnv propogation in <Perl> section
+ http://www.gossamer-threads.com/archive/mod_perl_C1/dev_F4/%5BMP2_BUG%5D_PerlPassEnv_issues_P70500/
+
+* there was a report about PerlRun leaking memory. the reporter didn't
+ give any more details, but I suspect that it's due to
+ ModPerl::Util::unload_package() which perfectly fits the timing when
+ the leak was introduced (when PerlRun started to use unload_package).
+
+ Report: http://gossamer-threads.com/lists/modperl/modperl/77162
+
+* most of the xs wrappers print no "Usage: " when wrong args/wrong
+ number of args are passed, would be nice to add the usage message
+ whenever incorrect arguments error is logged. e.g., when
+ APR::URI->parse() gets the wrong first arg (non-pool) it prints:
+
+ p is not of type APR::Pool at ...
+
+ whereas it's not so obvious that the function expected the pool
+ object, neither it specifies which ("arg number") of the arguments
+ is wrong.
+
+ possible solution: add a new field to the map files, which will be
+ used as a usage message whenever an argument error occurs.
+
+* 'SetHandler modperl' doesn't reset $|, so if anything turns it on
+ anywhere, it's going to stay that way. Meaning excessive flushing
+ probably causing a performance hit. I've tried to add the code to
+ reset it, but this requires getting a perl interpreter at the early
+ stage and it breaks several filter tests, which has relied before on
+ the coincidence that both the response handler and the filter were
+ run by the same interpreter (in particular this breaks the code
+ where push_handlers() uses a string as a handler, rather a CODE
+ reference, see t/filter/TestFilter/both_str_rec_add.pm, to
+ reproduce the problem, simply s/modperl/perl-script/)
+
+
+* Apache::PerlSection->dump() will not preserve tied'edness. This is
+ handled proprely in Storable, so either switch dump/restore to
+ non-human readable (-0.5) or borrow the same logic to dump/restore
+ tied objects.
+
+
+
+* Apache::Log compat issues:
+
+ Apache->warn, Apache::warn, Apache::Server->warn and
+ Apache->Apache::Server->log_error are all doing:
+ s = modperl_global_get_server_rec();
+ and this function is thread safe only during the startup.
+
+ possible solutions:
+
+ 1) enforce that these functions are used only at the server startup
+
+ 2) require +GlobalRequest, which gives us r->server, now thread
+ safe (though slow).
+
+ 3) drop them all from the API and move to compat.
+ [remember that Apache::warn is needed for registry scripts to
+ override warn()]
+
+ For Apache::warn and registry, the solution is to supply
+ GLOBAL::CORE::warn for the current request and get $r inside of it
+ and]
+
+ Report: Message-ID: <Pine.LNX.4.33.0206201011070.2590-100000@mako.covalent.net>
+ Status: <img alt="Doug, contemplating">
+
+* see if we can avoid touching environ[] until a fork() from Perl
+ happens
+
+* Apache::Status prints a bogus filename via B::CV (e.g. from the test
+ suite)
+
+ http://localhost:8529/status/perl/APR::Brigade::bootstrap/FUNCTION?cv_dump
+ Subroutine info for APR::Brigade::bootstrap
+ File: xYµ
+ Package: APR::Brigade
+ ...
+
+ notice the bogus filename. For some reason this problem doesn't
+ exist with APR::Bucket:
+
+ http://localhost:8529/status/perl/APR::Bucket::bootstrap/FUNCTION?cv_dump
+
+ I have tested that the bogus filename comes from $obj->FILE in
+ Apache::Stats::cv_file, where $obj is blessed into B::CV.
+
+ The problem has been noticed with threaded 5.8.1 perl, didn't test
+ any other builds.
+
+ Apparently it's a known to p5p problem:
+ http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-08/msg00514.html
+ http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-11/msg01126.html
+
+ Report:
+ http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=106893251911930&w=2
+ Priority: Low
+
+* mpxs_Apache2__RequestRec_GETC in Apache_RequestIO.h is out to be
+ reimplemented similar to read() w/o using the deprecated
+ client_block interface
+
+* Segfaults under Apache::Reload (could be uncovering a bug in mp):
+ http://marc.theaimsgroup.com/?t=111145169900002&r=1&w=2
+ owner: gozer
+-
diff --git a/2_0_13/todo/bugs_registry b/2_0_13/todo/bugs_registry
new file mode 100644
index 0000000..7aaece4
--- /dev/null
+++ b/2_0_13/todo/bugs_registry
@@ -0,0 +1,20 @@
+##########################
+# Registry specific bugs #
+##########################
+
+
+* An open issue with chdir, which is process-scoped. Arthur Bergman
+ has started the work on ex::threads::safecwd, which is discussed
+ here: http://www.perl.com/pub/a/2002/06/11/threads.html?page=2
+
+RegistryLoader:
+
+- chdir() needs to be adjusted when RegistryCooker implements it
+
+RegistryCooker:
+
+- consider not to use $$ in debug tracing. Not all platforms give out
+ a different pid for different threads.
+
+- some problems with setting the DEBUG() constant based on the value of
+ Apache->server->dir_config('ModPerl::RegistryCooker::DEBUG')
diff --git a/2_0_13/todo/design_notes b/2_0_13/todo/design_notes
new file mode 100644
index 0000000..3895bda
--- /dev/null
+++ b/2_0_13/todo/design_notes
@@ -0,0 +1,105 @@
+(dunno where to put it but don't want to lose these design notes, so
+just land them here for now)
+
+
+Filters: direct C api mapping
+--------------------
+
+Apache::register_output_filter($filtername, $callback, $filter_type)
+
+Apache::register_input_filter($filtername, $callback, $filter_type)
+
+ filter_type can be one of:
+ Apache::FTYPE_CONTENT
+ Apache::FTYPE_HTTP_HEADER
+ Apache::FTYPE_TRANSCODE
+ Apache::FTYPE_CONNECTION
+ Apache::FTYPE_NETWORK
+
+$r->add_output_filter($name, $ctx)
+$c->add_output_filter($name, $ctx)
+
+$r->add_input_filter($name, $ctx)
+$c->add_input_filter($name, $ctx)
+
+note: $ctx will default to NULL
+
+Filters: directives
+----------
+
+PerlInputFilterHandler
+
+PerlOutputFilterHandler
+
+each will be the equivalent of:
+
+ap_register_{input,output}_filter($handler_name, $handler, $filter_type)
+
+where:
+ $handler_name is the Perl name, at the moment is "MODPERL_OUTPUT" and
+ "MODPERL_INPUT", would be easy to switch that to the handler name
+
+ $handler is the modperl C callback
+
+ $filter_type defaults to AP_FTYPE_CONTENT, subroutine attributes can
+ be used to specify the filter_types list above
+
+ based on attributes, add_{input,output}_filter may need to happen at
+ different times, e.g. input filters who want to filter headers +
+ content vs. input filters who want to filter only content
+
+alternative to those directives would be:
+
+PerlInputFilter
+
+PerlOutputFilter
+
+combined with:
+
+SetInputFilter
+
+SetOutputFilter
+
+pros: can use Perl{Input,Output}Filter to register the filter in
+ httpd.conf, rather than using the API. can then call
+ $r->add_{input,output}_filter($filter_name) at request time
+
+cons: in the common case, requires two directives that use the same
+ values (the $handler_name)
+
+ - and/or -
+
+PerlSetInputFilter
+
+PerlSetOutputFilter
+
+as aliases for SetInputFilter, SetOutputFilter which also take care of
+filter registration (which PerlInputFilter, PerlOutputFilter would
+have done)
+
+pros: similar to Set{Input,Output}Filter
+ only need to use one directive
+
+cons: the filter module needs to register the filter in order to add
+ the filter at request time without using a directive
+ however: PerlModule Apache::FooFilter
+ where Apache::FooFilter registers the filter, can provide this
+ functionality without requiring new Perl{Input,Output}Filter
+ directives
+
+ - in any case -
+
+with the C api mapping it should be possible for a PerlModule to
+register the filter(s), then use the standard Set{Input,Output}Filter
+directives and the add_{input,output}_filter api at request time.
+
+note: no need to maintain a list of PerlFilters (like PerlModule,
+PerlRequire) since the directives trigger modperl_handler_new(), just
+like all other Perl*Handlers
+
+Filters: {get,set,push}_handlers
+-----------------------
+would be nice for Perl{Input,Output}FilterHandler to work with the
+modperl {get,set,push}_handlers api just like other Perl*Handlers
+
+
diff --git a/2_0_13/todo/docs b/2_0_13/todo/docs
new file mode 100644
index 0000000..4c48f8b
--- /dev/null
+++ b/2_0_13/todo/docs
@@ -0,0 +1 @@
+docs todo is located at modperl-docs/src/docs/2.0/TODO
diff --git a/2_0_13/todo/features_deprecated b/2_0_13/todo/features_deprecated
new file mode 100644
index 0000000..18f3624
--- /dev/null
+++ b/2_0_13/todo/features_deprecated
@@ -0,0 +1,28 @@
+these features with either:
+a) never be in 2.0
+b) only be in #ifdef MP_DEPRECATED
+c) be a form that was nothing like 1.xx (e.g. Apache::Leak)
+d) split off into something standalone on cpan
+
+- MaxModPerlRequestsPerChild
+
+- $r->seqno, $r->sent_header,
+ $r->query_string, $r->basic_http_header, $r->new_read,
+ $r->write_client, $r->read_client_block, $r->translate_name
+
+- $r->content, $r->args in-a-list-context (exist in Apache::compat)
+
+- $Apache::Server::Starting, $Apache::Server::ReStarting
+
+- modules:
+ + Apache::SIG: dead
+ + Apache::Symbol: unknown
+ + Apache::Leak: could be made useful
+ + Apache::RedirectLogFix: dead
+ + Apache::Include: was just an example
+ + Apache::Debug: could be make useful
+ + Apache::FakeRequest: should be built in
+ + Apache::httpd_conf: dead (to be replaced by new test framework)
+ + Apache::Symdump: unknown
+ + Apache::Opcode: was experimental, needs much attention to be
+ useful
diff --git a/2_0_13/todo/features_maybe b/2_0_13/todo/features_maybe
new file mode 100644
index 0000000..85c278e
--- /dev/null
+++ b/2_0_13/todo/features_maybe
@@ -0,0 +1,203 @@
+#########################
+# Nice to have features #
+#########################
+
+* If Apache::SubRequest::DESTROY gets invoked more than once on the
+ same object (directly and indirectly via object's exit of scope),
+ memory gets corrupted and some later unrelated requests get affected
+ badly (segfaults in unrelated areas). So we probably need to do the
+ same handling as APR::Pool, where we make sure that no matter how
+ DESTROY is called, it's always called only once, any consequent
+ calls can be made a NOP or assert. BTW, it's easy to reproduce the
+ problem, by simply calling $subrequest->DESTROY 3 times or so in a
+ raw, the server just hangs...
+
+* 'apachectl configtest' will not test perl modules, unless <perl>
+ section or PerlLoadModule has happeneded to be loaded (since by
+ default we start perl in the post-config phase. A possible solution
+ is to try to detect 'apachectl configtest' and force the interpreter
+ loading during the config phase, so that configtest will actually
+ work for mp2 too. there is also an opinion that there is no
+ problem, and configtest just checks the config file syntax. But the
+ problem is that users might be mislead and think that it tests
+ modperl too, and when doing a restart it may fail, even though
+ configtest said it's OK.
+
+* PerlPreConnectionHandler is implemented, but the 'void *csd' arg in
+ the callback is ignored. will require a modification of
+ modperl_callback_run_handlers to pass yet another optional argument.
+
+ Status: most likely nobody will ever want to use this option, so
+ don't waste time working on it.
+
+* Apache::FakeRequest:
+ since APR can be used outside of httpd, and we can alloc request_rec
+ and similar structures, it should be possible to bootstrap an
+ inside-httpd interface and outside-httpd interface. its not really
+ worthwhile looking at until APR actually installs its *.so or *.a
+ libraries somewhere apxs can find them. and, there's a bunch of util
+ functions (e.g. URI stuff) that is supposed to move from httpd into
+ apr-util.
+
+* could add support for embedding apache directives into perl
+ directives values, e.g. interpolating $ServerRoot
+
+ PerlSwitches -I$ServerRoot/lib/perl
+
+* Since now we have protocol modules, it'd be nice to have a similar
+ thing to PerlCleanupHandler, which works only for HTTP requests.
+ It should probably be called PerlConnectionCleanupHandler.
+
+ If we add it we should probably rename PerlCleanupHadndler to
+ PerlRequestCleanupHandler and keep the old name as a deprecated alias.
+
+ We could also have PerlServerCleanupHandler, but that's exactly what
+ PerlChildExitHandler does. Consider having ServerCleanup as an alias.
+
+config features:
+----------------
+
+- tie %ENV to r->subprocess_env so stores are added to
+ r->subprocess_env and fetches are looked up in there and elsewhere
+ (e.g. HTTP_* from r->headers_in). see modperl_env.c, current
+ implementation is not threadsafe and requires 5.7.2+
+
+- make 'PerlSetVar $Foo value' work like 'local $Foo = value'
+ for the given location
+
+- allow Perl*Handler's to have arguments in config files
+
+- allow <Perl></Perl> configuration sections to have read access to internal
+ configuration structures (would be nice if we could tie a %namespace::)
+
+- setuid/gid before running any Perl code
+
+- implement PerlINC (or similar) as a nicer interface for the working
+ PerlSwitches -Mlib=/home/dev1/lib/perl, to set different @INC for
+ different virtual hosts.
+ See the thread: http://marc.theaimsgroup.com/?t=100554858800001&r=1&w=2
+
+- a possible implementation of PerlOptions +Inherit, similar to
+ +Parent but which allows virtual hosts to inherit everything that
+ was loaded by the main server, at the point of their definition in
+ the config file. This can make it easier to write configuration
+ files where there is a common base of modules to be loaded in all
+ servers. Of course this can be done by putting all these common
+ modules and code into foo.pl and running it from the base server and
+ all virtual hosts.
+
+- PerlModule can be made more efficient using Perl_load_module
+
+ Status: it's possible to implement, but currently there is no way to
+ prevent from Perl logging the loading error messages to the
+ console
+ http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-03/msg00319.html
+
+perl language features:
+----------------------
+
+- @ARGV magic, tie to query string
+
+- sub handler : method ($) {}
+ call $class->new($r) and pass the returned object as the first and
+ only arg to the method handler
+
+- some mod_perlIO/PerlIO type methods for xs modules? (e.g. Apache::Peek)
+
+- possible to support BEGIN,CHECK,INIT blocks similar to how END is
+ supported via ModPerl::Global::special_list_{call,clear}
+
+
+
+optimization features:
+---------------------
+
+- copy-on-write SvPVX
+
+- hook Perl malloc into apr_pool
+
+- for "compiled handlers" w/ ithreads manage SV allocation via
+ server-lifetime apr_pool_t
+
+- "garbage collector" thread to walk padlists looking for certain things
+ worth releasing.
+
+- "mip manager" thread to watch # of active interpreters,
+ cloning/destroying when needed (rather than waiting for a request to
+ trigger)
+
+- use subpools per-callback/handler (might trim some memory bloat)
+ note: creating subpools requires a malloc mutex lock with threaded
+ mpms
+
+api:
+---
+
+- improve the "stacked handlers" implementation, including:
+ + allow push_handlers to have an additional argument, an array ref,
+ which will be passed to the handler as arguments, e.g.
+ $r->push_handlers("PerlHandler", \&some_sub, ['one', 'two', 'etc']);
+
+- might add an alias for $filter->connection (now we have $filter->c), to be
+ more intuitive since we have $r->connection.
+
+modules:
+-------
+
+- core Apache::SubProcess w/ proper CORE::GLOBAL::{fork,exec} support
+ + currently works only with $] >= 5.007003 (see the
+ apache/subprocess test)
+
+- It's possible that we will add:
+
+ #ifdef MP_APACHE_COMPAT
+ modperl_require_module("Apache::compat");
+ #endif
+
+ if MP_APACHE_COMPAT Makefile.PL option is true. But this adds bloat,
+ so this is just an option to consider.
+
+- Apache::File->tmpfile now lives only in compat. Consider adding
+ APR::File->mktemp (apr_file_mktemp) and a perlio layer
+ defined in terms of apr_file_t to use it.
+
+- Apache::MethodList was implemented but was not usefull enough.
+ Thread: http://marc.theaimsgroup.com/?t=109269086600003&r=1&w=2
+ Patch: http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=109278475112976&q=p6
+
+new modules:
+-----------
+
+- apache.pm: use apache '1.3b3';
+
+misc new stuff:
+--------------
+
+- 'make html'
+
+- 'make test_report'
+
+apache features that would be neat for mod_perl:
+-----------------------------------------------
+
+- "autoload" hook for configuration directives
+
+tools that may help us develop/maintain mp2
+-------------------------------------------
+- B::Xref
+
+- gcov: test code coverage
+ http://apr.apache.org/coverage/index.html
+ http://gozer.ectoplasm.org/mod_perl/coverage/report.html
+
+- valgrind (currently valgrind chokes when running apache, long before
+ we get to mod_perl). I've heard that we could use some special
+ #define controls to tell valgrind where to look and where not.
+
+- gprof
+
+- lxr
+
+- tinderbox
+
+
diff --git a/2_0_13/todo/features_missing b/2_0_13/todo/features_missing
new file mode 100644
index 0000000..fee5734
--- /dev/null
+++ b/2_0_13/todo/features_missing
@@ -0,0 +1,118 @@
+########################
+# mp1 missing features #
+########################
+
+### try to get this first post 2.0 release ###
+
+* mp2 test suite opens many files - quite a few failure reports were
+ due to the low shell file limit. But at the moment we can't tell
+ users why this have the problem. Gisle Aas has suggested that we
+ check whether the shell has a big enough setting for this limit and
+ either die explaining the situation or try to manually raise the
+ limit.
+
+ http://thread.gmane.org/gmane.comp.apache.mod-perl/16154
+
+ once implemented this should be ideally abstracted to be usable by
+ Apache-Test, and have a hook so each project can specify its own
+ min files limit, so other projects can benefit too.
+
+* directive handlers are supported but need some work for 1.x compat
+ - Apache::CmdParms::{GETC,getline} needs compat mapping, similar to
+ what Apache::Directive->as_string does, but one char or line at a time
+
+ - Automatic setting of cmd_args in @APACHE_MODULE_DIRECTIVE based on
+ function prototype
+
+* $r->child_terminate:
+ - Apache has no API for this (used to be ap_child_terminate). The
+ current solution is not ideal. Better trying to get ap_child_terminate
+ back in the httpd API.
+ - future ideas for threaded mpms: might consider knocking
+ off the current PerlInterpreter instead.
+
+* tied filehandle interface:
+ -EOF, TELL, SEEK
+ -READLINE - proper implementation (see comment in Apache::compat)
+ need to attempt to fix that interface so it'll work with IPC::Open* family
+
+* It'd be nice to have PAUSE and the clients support packages with
+ several versions, like mod_perl 1.0 and mod_perl 2.0, since once we
+ release it any dependency on mod_perl will be resolved as mod_perl
+ 2.0, when mod_perl 1.0 may be required instead.
+ owner: stas: talked to autrijus, he will start working on it, but
+ not sure when. we need to ping him every so often. but
+ it'll probably won't happen by the time we release 2.0.
+
+### other, less important things ###
+
+* Integrate the new perl feature: PL_use_safe_putenv (starting from
+ perl 5.8.6)
+ http://public.activestate.com/cgi-bin/perlbrowse?patch=23529 this is
+ needed to make it possible mod_php and mod_perl run at the same
+ time. Relevant threads:
+ http://www.gossamer-threads.com/lists/perl/porters/187753
+ http://www.phpbuilder.com/lists/php-install/2003092/0018.php
+
+ at the moment recompiling perl with -DPERL_USE_SAFE_PUTENV may or
+ may not work
+
+* $r->last is missing (it was provided explicitly by modperl, it's not
+ an apache thing) see modperl/src/modules/perl/Apache.xs
+
+* automate generation of xs/tables/current/apr/FunctionTable.pm
+ via Apache::ParseSource. This file contains a subset of
+ functions appearing in ModPerl::FunctionTable that are
+ needed when building APR.so, and is used when generating
+ the def/exp files on Win32/AIX.
+
+* Apache::PerlSections missing features for backwards compatibility:
+ - $Apache::ReadConfig::DocumentRoot
+ - Apache::PerlSections->store(filename)
+
+ Report: Philippe M. Chiasson <gozer@cpan.org>
+ Status: Philippe M. Chiasson <gozer@cpan.org> is working on it
+
+* PerlOpCodeMask (experimental in 1.xx)
+
+* die 404 (consider deprecating it)
+
+* mod_perl::import
+ - Apache->import:
+ required for exit/warn overridding
+ - use mod_perl2 qw(2.0 MethodHandlers Authen Authz [...]);
+ used to be able to specify what optionnal feature were required
+
+* Apache::test: tobe a compat stub around new test framework
+
+* Apache::src: tobe a compat stub around new build framework
+
+* hooks ordering is not implemented yet
+ Owner: geoff
+
+* $r->finfo:
+ need apr_finfo_t <-> struct stat conversion (might already be there,
+ haven't looked close enough yet)
+
+* $r->chdir_file:
+ not safe for threaded environments. should at least unshift @INC
+ with dirname $r->filename. consider overriding open() to resolve
+ relative filenames.
+
+* size_string() - can we use apr_strfsize ?
+
+* $r->send_fd:
+ need to figure out howto map PerlIO <-> apr_file_t
+ at the moment $r->send_fd is implement in Apache::compat, functions,
+ but does not have the performance benefits of ap_send_fd()
+ however, $r->sendfile is a new function that opens the file for you
+ and calls ap_send_fd() underneath. ap_send_fd() in APR doesn't work
+ with fd's which aren't files and of unknown length, therefore it cannot
+ be used for implementing 1.x compatible send_fd.
+ Solution: send_fd will require the length argument and there will be
+ no send_fd without the length argument as in mp1
+ Owner: stas
+
+* Apache::Debug:
+ Possibly work it differently, but certainly add support for dealing with $^M
+ Report: http://gossamer-threads.com/lists/modperl/modperl/77853
diff --git a/2_0_13/todo/features_new b/2_0_13/todo/features_new
new file mode 100644
index 0000000..3cd0096
--- /dev/null
+++ b/2_0_13/todo/features_new
@@ -0,0 +1,61 @@
+#######################
+# New features in mp2 #
+#######################
+
+* extend add_config to support add_config($multi_line_config). If the
+ passed argument is not a ref to an array, but a scalar should use
+ CR?LF to do the line split
+
+* PerlFooHandler -Bar is a NOOP when 'PerlOptions AutoLoad' is in
+ effect, whereas it should prevent autloading.
+ See:
+ modperl_handler_new in modperl_handler.c
+ modperl_hash_handlers in modperl_mgv.c
+
+* filters tie handle/perlio interface
+
+ both input/output filters should provide a tiehandle and/or perlio
+ interface.
+
+ Perl tiehandle methods include the following, '+' indicates must have, '-'
+ indicates not possible / doesn't make sense (though might require noop
+ stubs), '~' indicates would be nice if possible, '?' indicates unsure:
+
+ + TIEHANDLE
+ + PRINT
+ + PRINTF
+ + WRITE
+ + READLINE
+ + GETC
+ + READ
+ + CLOSE
+ ? UNTIE
+ ? DESTROY
+ + BINMODE (noop)
+ ? OPEN
+ ~ EOF
+ - FILENO
+ ~ SEEK
+ ~ TELL
+
+* maybe functions in xs/maps/(apache|apr)_functions.map
+
+* Apache->request:
+ need to deal with subclass objects which are not a request_rec
+ (e.g. HASH ref)
+ Owner: gozer
+
+* Apache::SizeLimit
+ o Need to work out the details of the implementation of the garbage
+ collection thread for the threaded mpms as originally suggested by
+ doug. The issue with threads is that there is no way to know the
+ thread's size, can we use B::Size and B::TerseSize?
+
+ prefork:
+ Apache::SizeLimit - done
+ Apache::GTopLimit - Owner: stas
+ threaded:
+ Garbage Collector thread
+
+ => Ideally the tools should work transparently with threaded and
+ non-threaded mpms, but how?
diff --git a/2_0_13/todo/features_optimization b/2_0_13/todo/features_optimization
new file mode 100644
index 0000000..994ccad
--- /dev/null
+++ b/2_0_13/todo/features_optimization
@@ -0,0 +1,37 @@
+###############################################
+# working features but requiring optimization #
+###############################################
+
+* all autogenerated xs methods that return char * are now using
+ sv_setpv() which always copies the string. See if we somehow can
+ avoid the copy. If we do so, we need to be careful with method which
+ take a pool argument, such as:
+ Apache::ServerUtil
+ - mpxs_Apache2__ServerUtil_server_root_relative
+ Apache::URI:
+ - ap_construct_server
+ - ap_construct_url
+ APR::URI
+ - mpxs_apr_uri_parse
+ Apache::Util
+ - ap_ht_time
+ - escape_path
+ for which we need to attach the pool object used to create those
+ strings as a magic.
+
+* optimize modperl_callback_current_callback_(set|get) to use
+ numerical equivalents of the phase names, instead of doing expensive
+ memory allocs and string comparison operations. And only give the
+ real string in the perl get API.
+
+* consider using the temp pool for things that are needed only during
+ the configuration and can be dropped before the actual serving is
+ started. that pool gets destroyed right after the post-config phase
+ is over.
+
+* currently when ithreads-enabled perl is used anon-sub handlers are
+ always deparsed and non-cached. there are several cases when this
+ can be optimized. See modperl_handler_new_anon in modperl_handler.c
+
+* modperl_package_unload() and modperl_xs_dl_*() share some duplicated
+ logic. The managment of DynaLoaded modules could be somewhat cleaner.
diff --git a/2_0_13/todo/features_registry b/2_0_13/todo/features_registry
new file mode 100644
index 0000000..1df0725
--- /dev/null
+++ b/2_0_13/todo/features_registry
@@ -0,0 +1,94 @@
+#####################
+# Registry Features #
+#####################
+
+- port Apache::PerlRunXS
+
+- replace the local implementation of finfo() when ported to mod_perl 2.0
+
+- $r->chdir_file is not handled/implemented, see todo/api.txt unsafe!
+
+- $Apache::Server::CWD doesn't exist
+
+- need to figure out what's happening with
+ ModPerl::Registry::MarkLine, why it's not on by default?
+
+- a cousin of convert_script_to_compiled_handler() in 1.x used to have
+ 'undef &{"$o->[PACKAGE]\::handler"}' to avoid redefine handler()
+ warnings in case a user has used -w. also see the undef_functions on
+ the next line.
+
+- child_terminate is not implemented see
+ convert_script_to_compiled_handler().
+
+- print STDERR is buffered in test handlers, whereas warn() works
+ normally. select() helps, but STDERR should be unbuffered in first
+ place.
+
+- in namespace_from_filename() should test whether a file is a symlink
+ and if so use readlink() to get the real filename.
+
+- documentation
+
+- acl support via 'filetest qw(access)'. It was decided that having
+ this feature by default will be too expensive, because of the
+ overhead it adds. The solution was to add a sub-class that will
+ provide that functionality. It wasn't decided whether it'll be in
+ the core or should live on CPAN. Also it wasn't decided whether
+ RegistryCooker should provide the necessary implementation
+ callbacks. See:
+ http://marc.theaimsgroup.com/?t=107636627000001&r=1&w=2
+
+### optimizations ###
+
+- currently the default is to strip __DATA__|__END__ and everything
+ after that, which incurs a little overhead because of the s/// on
+ the contents of the file. This "feature" wasn't in 1.x, so may
+ consider to make it optional.
+
+### nice to have ###
+
+- Bjarni R. Einarsson <bre@klaki.net> has suggested this Registry hack
+ http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=98961929702745&w=2
+ Message-ID: <20010511221101.A20868@diskordiah.mmedia.is>
+
+- the closure issue:
+ there was a suggestion from raptor to use goto() to leave the code
+ unwrapped in the sub handler, which will solve the closure problem,
+ but the problem is that once you leave a subroutine with goto() you
+ cannot return, because you aren't in the sub anymore.
+
+ barrie has suggested a different approach, which requires adding
+ special tags to the script which help to parse the code, and shuffle
+ things around without putting subs inside the 'sub handler', but
+ this requires a lot of code understanding from a user, and if its
+ gained it's probably easier to fix the script so closure effect
+ won't happen. However barrie's suggestion can be easily added, by
+ overriding convert_script_to_compiled_handler().
+
+- global variables persistance: could have the cooker option to flush
+ globals in the autogenerated package at the end of each
+ request. (not packages use()'d from this package)
+
+- could also try to privide an optional workaround for the problem
+ with libs collisions as explained here:
+ http://perl.apache.org/docs/1.0/guide/porting.html#Name_collisions_with_Modules_and
+
+- It's a known kludge with mod_perl scripts coming from mod_cgi which
+ use -M for file mtime comparisons, but are not aware of the fact
+ that $^T is not getting reset on each request. So may be the cooker
+ should have an option to reset $^T on each request.
+
+- develop a cooker() that cooks/modifies a registry package based on
+ PerlSetVar variables. So for example a user can modify a behavior of
+ an existing package (stat/donotstat...) and giving it a new name at
+ the same time. Kinda flag-based inheritance.
+
+* protect registry classes from bad scripts which try to assassinate $r
+ Report: http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=106153785129782&w=2
+ Status: (stas) i'm not sure whether we really need this feature,
+ since it's the first time in the last 6 years we had a
+ problem with bad user code of this kind. let's keep it in
+ the patches until we have a real need for it.
+ Priority: very low
+
diff --git a/2_0_13/todo/release b/2_0_13/todo/release
new file mode 100644
index 0000000..a88bada
--- /dev/null
+++ b/2_0_13/todo/release
@@ -0,0 +1,57 @@
+##################################################
+# Things to be resolved for mod_perl 2.0 release #
+##################################################
+
+-- see also todo/api_status
+-- see also todo/release-checklist
+
+someone has asked to make $r->request_time settable
+
+-------------
+
+The following items need more work in order to work with blead-perl:
+
+http://svn.apache.org/viewcvs?rev=209859&view=rev
+perl blead fix: in 5.9.3 HvPMROOT was completely removed, temporary
+using Perl_Imodglobal_ptr(thx)))->xmg_magic (which fails on perl_clone
+from ithreads, but otherwise works). this must be replaced with a
+better solution once we find it.
+
+http://svn.apache.org/viewcvs?rev=209861&view=rev
+blead perl temp fix: some recent change introduced tainting problems,
+will remove the workaround once blead perl is fixed
+
+
+
+
+-------------
+
+MP_STATIC_EXTS=1 must link all extensions but APR.so. At the moment
+the following are not linked:
+
+ APR/Const.so APR/PerlIO.so Apache/Const.so ModPerl/Const.so
+
+owner: ???
+
+note: when testing MP_STATIC_EXTS=1 build we must ensure that there is
+no preinstalled mod_perl2. Since if there is a preinstall of a normal
+build, MP_STATIC_EXTS=1 will be not properly tested, as the
+preinstalled .so modules will be loaded. A potential solution: when
+MP_STATIC_EXTS=1 is used change .pm files not to load the .xs
+extensions!
+
+-------------
+
+When running as root and A-T figures it can't run the test suite
+(perms) it'll ask users if she wants to skip the test suite, if this
+happens:
+
+ Skip the test suite? [No] yes
+ Skipping the test suite execution, while returning success status
+ cd ModPerl-Registry && make test
+
+she gets to run the registry test suite anyway, since the top level
+test suite was successful (needed to make cpan/plus installers
+happy). Not sure what's the best solution here.
+
+---------------
diff --git a/2_0_13/todo/tests_issues b/2_0_13/todo/tests_issues
new file mode 100644
index 0000000..07ca7a0
--- /dev/null
+++ b/2_0_13/todo/tests_issues
@@ -0,0 +1,25 @@
+######################################
+# test suite issues and improvements #
+######################################
+
+- As the number of tests grows it takes longer to start the test
+ suite. Under threaded mpms it can take a very long time on a loaded
+ machine (10 minutes and more). At the moment we keep on bumping the
+ startup timeout, but there is always someone with a slower/more
+ loaded machine, for whom this timeout is too low, and the tests
+ suite misleadingly fails to start. So may be we must start thinking
+ to split the existing test suite into several smaller suites (for
+ example we already have a separate ModPerl-Registry test suite). If
+ we do perl/ithreads* and any tests definging +Clone/+Parent tests
+ should definitely be moved out from the main suite, as they cause
+ the biggest overhead (due to perl_clone).
+
+- TestDirective::perlloadmodule6 should be the first perlloadmodule
+ test to run, so we can test how mod_perl starts from vhost (there
+ was a segfault before). But since other tests define PerlSwitches
+ TestDirective::perlloadmodule6 must be configured afer them. so if
+ we introduce new tests suites, this test needs to be moved there
+ (may be its own test suite or co-existing with other tests which
+ don't use PerlSwitches and trigger early server startup.
+
+
diff --git a/2_0_13/todo/tests_wanted b/2_0_13/todo/tests_wanted
new file mode 100644
index 0000000..c93a944
--- /dev/null
+++ b/2_0_13/todo/tests_wanted
@@ -0,0 +1,17 @@
+#################
+# wanted tests #
+#################
+
+- test that we properly set the error-notes tably entry on
+ HTTP_INTERNAL_SERVER_ERROR (is sub-request check REDIRECT_ERROR_NOTES)
+ o test with plain handlers
+ o test with registry (as we set it twice? once in registry and once
+ more in the handlers?)
+
+ mp1 has some sort of related test in t/net/perl/server_error.pl:
+ my $note = $r->prev->notes('error-notes')
+
+- We can put Apache::Scoreboard to a good use for Apache::Test. For
+ example we can test with it Apache::SizeLimit or
+ Apache::Watchdog::RunAway, since both kill processes, and we need to
+ make sure that the process went away.
diff --git a/2_0_13/util/apr_arg_check.pl b/2_0_13/util/apr_arg_check.pl
new file mode 100755
index 0000000..301a4fd
--- /dev/null
+++ b/2_0_13/util/apr_arg_check.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use lib qw(lib);
+
+use strict;
+use Apache2::FunctionTable ();
+
+#utility for checking apr_ argument conventions
+
+my $tx = '_t\s*\*+';
+
+for my $entry (@$Apache2::FunctionTable) {
+ my $name = $entry->{name};
+ my $args = $entry->{args};
+ next unless @$args and $name =~ /^apr_/;
+
+ my $has_type_arg = 0;
+ for my $arg (@$args) {
+ my $type = $arg->{type};
+ next unless $type =~ s/$tx$//o;
+ $has_type_arg = $name =~ /^\Q$type/;
+ }
+ next unless $has_type_arg;
+
+ my $i = 0;
+ for my $arg (@$args) {
+ $i++;
+ my $type = $arg->{type};
+ $type =~ s/$tx//o;
+
+ if ($name =~ /^\Q$type/) {
+ last if $i == 1;
+ }
+ else {
+ next;
+ }
+ if ($i > 1) {
+ print "'$arg->{name}' should be the first arg:\n";
+ print " $entry->{return_type}\n $name(",
+ (join ', ', map "$_->{type} $_->{name}", @$args),
+ ")\n\n";
+ }
+ }
+}
diff --git a/2_0_13/util/apr_pool_check.pl b/2_0_13/util/apr_pool_check.pl
new file mode 100755
index 0000000..056c8cf
--- /dev/null
+++ b/2_0_13/util/apr_pool_check.pl
@@ -0,0 +1,56 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+#check which apr_ functions do not have access to a pool
+
+use lib qw(lib);
+
+use strict;
+use Apache2::SourceTables ();
+
+my($functions, @nopool);
+
+#incomplete types (C::Scan only scans *.h, not *.c) we know have an apr_pool_t
+my %private = map { $_, 1 } qw{
+apr_dir_t apr_file_t apr_dso_handle_t apr_hash_t apr_hash_index_t apr_lock_t
+apr_socket_t apr_pollfd_t apr_threadattr_t apr_thread_t apr_threadkey_t
+apr_procattr_t apr_xlate_t apr_dbm_t apr_xml_parser
+};
+
+for my $entry (@$Apache2::FunctionTable) {
+ next unless $entry->{name} =~ /^apr_/;
+
+ $functions++;
+
+ unless (grep { find_pool($_->{type}) } @{ $entry->{args} }) {
+ push @nopool, $entry;
+ }
+}
+
+my $num_nopool = @nopool;
+
+print "$num_nopool functions (out of $functions) do not have access to a pool:\n\n";
+
+for my $entry (@nopool) {
+ print "$entry->{return_type} $entry->{name}(",
+ (join ', ', map "$_->{type} $_->{name}", @{ $entry->{args} }),
+ ")\n\n";
+}
+
+sub find_pool {
+ my $type = shift;
+
+ return 1 if $type =~ /^apr_pool_t/;
+
+ $type =~ s/\s+\*+$//;
+ $type =~ s/^(const|struct)\s+//g;
+
+ if (my $elts = $Apache2::StructureTable{$type}) {
+ return 1 if $private{$type};
+
+ for my $e (@$elts) {
+ next if $e->{type} =~ /^$type/;
+ return 1 if find_pool($e->{type});
+ }
+ }
+}
diff --git a/2_0_13/util/cvsize.pl b/2_0_13/util/cvsize.pl
new file mode 100755
index 0000000..8e6682c
--- /dev/null
+++ b/2_0_13/util/cvsize.pl
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+#get an idea of how much space the XS interface will eat
+#build/source_scan.pl must be run first
+#see pod/modperl_sizeof.pod
+
+use strict;
+use Apache2::FunctionTable ();
+use Apache2::StructureTable ();
+
+use constant sizeofCV => 254;
+
+my $size = 0;
+my $subs = 0;
+
+for my $entry (@$Apache2::FunctionTable) {
+ $size += sizeofCV + ((length($entry->{name}) + 1) * 2);
+ $subs++;
+}
+
+for my $entry (@$Apache2::StructureTable) {
+ my $elts = $entry->{elts} || [];
+ next unless @$elts;
+
+ for my $e (@$elts) {
+ $size += sizeofCV + ((length($e->{name}) + 1) * 2);
+ $subs++;
+ }
+}
+
+print "$subs subs, $size estimated bytes\n";
diff --git a/2_0_13/util/getdiff.pl b/2_0_13/util/getdiff.pl
new file mode 100755
index 0000000..5b4cbb0
--- /dev/null
+++ b/2_0_13/util/getdiff.pl
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# this script creates a diff against SVN
+# and against /dev/null for all files in ARGV
+# and prints it to STDOUT
+#
+# e.g.
+# getdiff.pl t/modules/newtest t/response/TestModules/NewTest.pm \
+# > newtest.patch
+#
+# the generated patch can be applied with
+# patch -p0 < newtest.patch
+
+# cvs diff
+my $o = `svn diff`;
+
+for (@ARGV) {
+ $o .= "\n";
+ $o .= `diff -u /dev/null $_`
+}
+
+print $o;
+
diff --git a/2_0_13/util/methodlookup_check.pl b/2_0_13/util/methodlookup_check.pl
new file mode 100755
index 0000000..95da6fd
--- /dev/null
+++ b/2_0_13/util/methodlookup_check.pl
@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# this script checks whether all XS methods are known to ModPerl::MethodLookup
+
+use strict;
+use warnings;
+
+use lib "lib";
+
+use ModPerl::MethodLookup;
+
+# methods/classes ModPerl::MethodLookup knows about
+my %known = ();
+for (ModPerl::MethodLookup::avail_methods()) {
+ my ($modules_hint, @modules) = ModPerl::MethodLookup::lookup_method($_);
+ $known{$_} = { map {$_ => 1} @modules};
+}
+
+# real XS methods
+my %real = ();
+my $in = qx{grep -Ir newXS WrapXS};
+while ($in =~ m{WrapXS/(\w+)/(\w+)/.*?newXS\("(?:.+)::(.+)"}g) {
+ $real{$3}{"$1\::$2"}++;
+}
+
+# now check what's missing
+my @miss = ();
+for my $method (sort keys %real) {
+ for my $module (sort keys %{ $real{$method} }) {
+ #printf "%-25s %s\n", $method, $module unless $known{$method}{$module};
+ push @miss, sprintf "%-25s %s\n", $module, $method unless $known{$method}{$module};
+ }
+}
+
+print @miss ? sort(@miss) : "All methods are known by ModPerl::MethodLookup\n";
diff --git a/2_0_13/util/perl_bloat.pl b/2_0_13/util/perl_bloat.pl
new file mode 100755
index 0000000..421d393
--- /dev/null
+++ b/2_0_13/util/perl_bloat.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+# perlbloat.pl 'some perlcode' 'more perl code'
+# perlbloat.pl Foo/Bar.pm Bar/Tar.pm
+# perlbloat.pl Foo::Bar Bar::Tar
+
+no warnings;
+
+use GTop ();
+
+my $gtop = GTop->new;
+
+my $total = 0;
+for (@ARGV) {
+
+ my $code = $_;
+ file2package($_) if /\S+\.pm$/;
+
+ my $before = $gtop->proc_mem($$)->size;
+
+ if (eval "require $_" ) {
+ eval {
+ $_->import;
+ };
+ }
+ else {
+ eval $_;
+ die $@ if $@;
+ }
+
+ my $after = $gtop->proc_mem($$)->size;
+ printf "%-30s added %s\n", $_, GTop::size_string($after - $before);
+ $total += $after - $before;
+}
+
+print "-" x 46, "\n";
+printf "Total added %30s\n", GTop::size_string($total);
+
+sub file2package {
+ $_[0] =~ s|/|::|g;
+ $_[0] =~ s|\.pm$||;
+}
+
diff --git a/2_0_13/util/sizeof.pl b/2_0_13/util/sizeof.pl
new file mode 100644
index 0000000..1a6d3ec
--- /dev/null
+++ b/2_0_13/util/sizeof.pl
@@ -0,0 +1,62 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+#calculate structure sizes listed in pod/modperl_sizeof.pod via sizeof()
+
+use strict;
+
+use ExtUtils::Embed;
+use Config;
+
+my $file = shift || 'pod/modperl_sizeof.pod';
+
+open my $pod, $file or die "open $file: $!";
+
+FINDSTRUCT: {
+ while (<$pod>) {
+ next unless /^\s*(\w+)\s*=\s*\{/;
+ my $name = $1;
+ my $size = sizeof($name, $pod);
+ print "sizeof $name => $size\n";
+ redo FINDSTRUCT;
+ }
+}
+
+sub sizeof {
+ my($struct, $h) = @_;
+
+ my @elts;
+
+ while (<$h>) {
+ last if /^\s*\}\;$/;
+ next unless m:(\w+).*?//\s*(.*):;
+ push @elts, "sizeof($2) /* $1 */";
+ }
+
+ my $name = "perl_sizeof_$struct";
+ my $tmpfile = "$name.c";
+ open my $fh, '>', $tmpfile or die "open $tmpfile: $!";
+
+ local $" = " + \n";
+
+ print $fh <<EOF;
+#include <stdio.h>
+#define PERLIO_NOT_STDIO 0
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#undef fprintf
+int main(void) {
+ int size = @elts;
+ fprintf(stdout, "%d", size);
+ return 1;
+}
+EOF
+
+ my $opts = ccopts();
+ system "$Config{cc} -o $name $tmpfile $opts";
+
+ my $size = `$name`;
+
+ unlink $name, $tmpfile;
+
+ return $size;
+}
diff --git a/2_0_13/util/source_stats.pl b/2_0_13/util/source_stats.pl
new file mode 100755
index 0000000..fc502b0
--- /dev/null
+++ b/2_0_13/util/source_stats.pl
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+
+use lib qw(lib);
+
+use strict;
+use Apache2::FunctionTable ();
+use Apache2::StructureTable ();
+
+my %stats;
+
+for my $entry (@$Apache2::FunctionTable) {
+ unless ($entry->{name} =~ /^(ap|apr)_/) {
+ #print "found alien function $entry->{name}\n";
+ next;
+ }
+
+ $stats{functions}->{$1}++;
+}
+
+for my $entry (@$Apache2::StructureTable) {
+ my $elts = $entry->{elts};
+ my $type = $entry->{type};
+
+ my $c = $type =~ /^apr_/ ? "apr" : "ap";
+ @$elts = () if $type =~ /^ap_LINK/;
+ if (@$elts) {
+ $stats{typedef_structs}->{$c}++;
+ $stats{struct_members}->{$c} += @$elts;
+ }
+ else {
+ $stats{typedefs}->{$c}++;
+ }
+}
+
+while (my($name, $tab) = each %stats) {
+ printf "%d %s\n", $tab->{ap} + $tab->{apr}, $name;
+ for (qw(apr ap)) {
+ printf "%6s: %d\n", $_, $tab->{$_};
+ }
+}
diff --git a/2_0_13/util/xs_check.pl b/2_0_13/util/xs_check.pl
new file mode 100644
index 0000000..01ec89b
--- /dev/null
+++ b/2_0_13/util/xs_check.pl
@@ -0,0 +1,109 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+use lib qw(Apache-Test/lib lib xs/tables/current);
+
+use strict;
+use warnings qw(FATAL all);
+
+use ModPerl::TypeMap ();
+use ModPerl::FunctionMap ();
+use ModPerl::StructureMap ();
+use ModPerl::WrapXS ();
+use ModPerl::MapUtil qw(disabled_reason);
+
+my %check = (
+ types => ModPerl::TypeMap->new,
+ functions => ModPerl::FunctionMap->new,
+ structures => ModPerl::StructureMap->new,
+);
+
+my %missing;
+while (my($things, $obj) = each %check) {
+ $missing{$things} = $obj->check;
+ if (my $missing = $missing{$things}) {
+ my $n = @$missing;
+ print "$n $things are not mapped:\n";
+ print " $_\n" for sort @$missing;
+ }
+ else {
+ print "all $things are mapped\n";
+ }
+}
+
+my %check_exists = (
+ functions => $check{functions},
+ structure_members => $check{structures},
+ types => $check{types},
+);
+
+while (my($things, $obj) = each %check_exists) {
+ if (my $missing = $obj->check_exists) {
+ my $n = @$missing;
+ print "$n mapped $things do not exist:\n";
+ print " $_\n" for sort @$missing;
+ }
+ else {
+ print "all mapped $things exist\n";
+ }
+}
+
+my %unmapped = map { $_,1 } @{ $missing{functions} } if $missing{functions};
+my $typemap = $check{types};
+my $function_map = $check{functions};
+my @missing;
+
+for my $entry (@$Apache2::FunctionTable) {
+ my $func;
+ my $name = $entry->{name};
+ next if $unmapped{$name};
+ next unless $function_map->{map}->{$name};
+ next if $func = $typemap->map_function($entry);
+ push @missing, $name;
+}
+
+if (@missing) {
+ my $n = @missing;
+ print "unable to glue $n mapped functions:\n";
+ print " $_\n" for sort @missing;
+}
+else {
+ print "all mapped functions are glued\n";
+}
+
+my $stats = ModPerl::WrapXS->new->stats;
+my($total_modules, $total_xsubs);
+
+while (my($module, $n) = each %$stats) {
+ $total_modules++;
+ $total_xsubs += $n;
+}
+
+print "$total_modules total modules, ",
+ "$total_xsubs total xsubs\n";
+
+while (my($module, $n) = each %$stats) {
+ print "$module: $n\n";
+}
+
+for (qw(functions structure_members)) {
+ my $disabled = $check_exists{$_}->disabled;
+ my $total = 0;
+ for my $names (values %$disabled) {
+ $total += @$names;
+ }
+ print "$total $_ are not wrapped:\n";
+ while (my($r, $names) = each %$disabled) {
+ printf "%4d are %s\n", scalar @$names, disabled_reason($r);
+ }
+}
+
+if (@ARGV) {
+ my $key = '!';
+ for (qw(functions structure_members)) {
+ my $disabled = $check_exists{$_}->disabled;
+ my $names = $disabled->{$key};
+ printf "%s $_:\n", disabled_reason($key);
+ for my $name (sort @$names) {
+ print " $name\n";
+ }
+ }
+}
diff --git a/2_0_13/xs/APR/APR/APR.pm b/2_0_13/xs/APR/APR/APR.pm
new file mode 100644
index 0000000..b06a3b6
--- /dev/null
+++ b/2_0_13/xs/APR/APR/APR.pm
@@ -0,0 +1,36 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package APR;
+
+use DynaLoader ();
+our $VERSION = '0.009000';
+our @ISA = qw(DynaLoader);
+
+#dlopen("APR.so", RTDL_GLOBAL); so we only need to link libapr.a once
+# XXX: see xs/ModPerl/Const/Const.pm for issues of using 0x01
+use Config ();
+use constant DL_GLOBAL =>
+ ( $Config::Config{dlsrc} eq 'dl_dlopen.xs' && $^O ne 'openbsd' ) ? 0x01 : 0x0;
+sub dl_load_flags { DL_GLOBAL }
+
+unless (defined &APR::XSLoader::BOOTSTRAP) {
+ __PACKAGE__->bootstrap($VERSION);
+ *APR::XSLoader::BOOTSTRAP = sub () { 1 };
+}
+
+1;
+__END__
diff --git a/2_0_13/xs/APR/APR/APR.xs b/2_0_13/xs/APR/APR/APR.xs
new file mode 100644
index 0000000..bf267bc
--- /dev/null
+++ b/2_0_13/xs/APR/APR/APR.xs
@@ -0,0 +1,74 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+#ifdef MP_HAVE_APR_LIBS
+# define APR_initialize apr_initialize
+# define APR_terminate apr_terminate
+#else
+# define APR_initialize()
+# define APR_terminate()
+#endif
+
+#ifdef MP_HAVE_APR_LIBS
+
+/* XXX: APR_initialize doesn't initialize apr_hook_global_pool, needed for
+ * work outside httpd, so do it manually PR22605 */
+#include "apr_hooks.h"
+static void extra_apr_init(pTHX)
+{
+ if (apr_hook_global_pool == NULL) {
+ apr_pool_t *global_pool;
+ apr_status_t rv = apr_pool_create(&global_pool, NULL);
+ if (rv != APR_SUCCESS) {
+ PerlIO_printf(PerlIO_stderr(),
+ "Fatal error: unable to create global pool "
+ "for use with by the scoreboard");
+ }
+ /* XXX: mutex locking? */
+ apr_hook_global_pool = global_pool;
+ }
+ {
+ apr_file_t *stderr_apr_handle;
+ apr_status_t rv = apr_file_open_stderr(&stderr_apr_handle,
+ apr_hook_global_pool);
+ if (rv != APR_SUCCESS) {
+ PerlIO_printf(PerlIO_stderr(),
+ "Fatal error: failed to open stderr ");
+ }
+ modperl_trace_level_set(stderr_apr_handle, NULL);
+ }
+
+}
+#else
+# define extra_apr_init(aTHX)
+#endif
+
+MODULE = APR PACKAGE = APR
+
+PROTOTYPES: disable
+
+BOOT:
+ file = file; /* -Wall */
+ APR_initialize();
+ extra_apr_init(aTHX);
+
+void
+END()
+
+ CODE:
+ APR_terminate();
diff --git a/2_0_13/xs/APR/APR/Makefile.PL b/2_0_13/xs/APR/APR/Makefile.PL
new file mode 100644
index 0000000..edbd108
--- /dev/null
+++ b/2_0_13/xs/APR/APR/Makefile.PL
@@ -0,0 +1,109 @@
+use strict;
+use warnings;
+
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+require ModPerl::Code;
+use Apache2::Build ();
+use Config;
+use File::Spec::Functions;
+
+use constant WIN32 => Apache2::Build::WIN32;
+use constant CYGWIN => Apache2::Build::CYGWIN;
+use constant SOLARIS => $^O eq 'solaris';
+use constant BUILD_APREXT => Apache2::Build::BUILD_APREXT;
+
+my %args;
+
+%args = map { split /=/, $_, 2 } @ARGV;
+
+$args{NAME} = 'APR';
+$args{VERSION_FROM} = 'APR.pm';
+
+my $libs = '';
+$libs = delete $args{LIBS} if $args{LIBS};
+
+my $build = ModPerl::BuildMM::build_config();
+
+my $ccopts = $build->ccopts;
+
+# avoid referencing &perl_module outside of mod_perl
+$ccopts .= ' -DMP_IN_XS';
+
+$args{CCFLAGS} = $ccopts;
+
+my @apru_link_flags = $build->apru_link_flags;
+$libs .= join ' ', @apru_link_flags if @apru_link_flags;
+
+if (WIN32) {
+ $libs =~ s{/libpath:}{-L}g;
+ $libs =~ s{(\S+)\.lib}{-l$1}g;
+}
+
+if (BUILD_APREXT) {
+ my $mp_apr_lib = $build->mp_apr_lib;
+
+ if (CYGWIN) {
+ # For Cygwin compatibility, set $mp_apr_lib before the apache libs
+ $libs = qq{ $mp_apr_lib } . $libs;
+ } else {
+ $libs .= qq{ $mp_apr_lib };
+ }
+}
+
+if (SOLARIS && $libs) {
+ # EU::MM sets LD_RUN_PATH (for linking) based on -L options in LIBS.
+ # LD_RUN_PATH is getting overridden by the specified -R path.
+ # The -R specified is from the perl config's lddflags.
+ # Therefore -R has to be added with the appropriate paths rather
+ # than using LD_RUN_PATH, because it gets overridden.
+
+ # make sure that all -L, -R from libs are moved
+ # to the beginning of lddflags.
+ my $extralddflags = join " ", $libs =~ /(-[LR]\S+)/g;
+
+ # -R makes sure that these paths will be used
+ $extralddflags =~ s{-L(\S+)}{-L$1 -R$1}g;
+ $args{LDDLFLAGS} = "" unless exists $args{LDDLFLAGS};
+ $args{LDDLFLAGS} = join " ", $args{LDDLFLAGS}, $extralddflags,
+ $build->perl_config('lddlflags');
+
+ # -R are now copied to LDDFLAGS, but leave -L's in LIBS --
+ # EU::MM needs it.
+ $libs =~ s{-R\S+}{}g;
+}
+
+$args{LIBS} = [$libs] if $libs;
+
+my $srcdir = '../../../src/modules/perl';
+
+# link the following into APR.so so other APR:: modules can be used
+# outside of httpd
+my @names = ModPerl::Code::src_apr_ext();
+
+my(@obj, @clean, %src);
+for (@names) {
+ push @obj, join '.', $_, 'o';
+ my $cfile = join '.', $_, 'c';
+ push @clean, $cfile;
+ $src{$cfile} = "$srcdir/$cfile";
+}
+
+$args{OBJECT} = BUILD_APREXT() ? "APR.o" : "APR.o @obj";
+$args{clean} = { FILES => "@clean" };
+
+ModPerl::BuildMM::WriteMakefile(%args);
+
+# avoid redefined warnings from imported postamble symbol from
+# elsewhere in other Makefile.PL files
+no warnings 'redefine';
+sub MY::postamble {
+ my $self = shift;
+ my $string = $self->ModPerl::BuildMM::MY::postamble;
+
+ $string .= join '', map {
+ "$_: $src{$_}\n\t\$(CP) $src{$_} .\n";
+ } sort keys %src;
+
+ return $string;
+}
diff --git a/2_0_13/xs/APR/APR/apr-test b/2_0_13/xs/APR/APR/apr-test
new file mode 100644
index 0000000..9c70bd6
--- /dev/null
+++ b/2_0_13/xs/APR/APR/apr-test
@@ -0,0 +1,61 @@
+#!perl
+
+use Test;
+
+plan tests => 8;
+
+use blib;
+use warnings FATAL => 'all';
+use strict;
+use APR ();
+use APR::UUID ();
+use APR::Pool ();
+use APR::Lock ();
+use APR::Util ();
+use APR::Base64 ();
+use APR::Signal ();
+
+my $status;
+
+my $uuid = APR::UUID->new->format;
+
+ok $uuid;
+
+my $p = APR::Pool->new;
+
+ok $p;
+
+my $lock = APR::Lock->new($p, 0, 1, "lock.file");
+$status = $lock->acquire and die APR::strerror($status);
+$status = $lock->release and die APR::strerror($status);
+
+$status = APR::password_validate("one", "two");
+my $str = APR::strerror($status);
+ok $str eq "passwords do not match";
+
+ok $status;
+
+my $bytes = APR::generate_random_bytes(10);
+
+ok length($bytes) == 10;
+
+my $encoded = APR::Base64::encode($bytes);
+
+#print "encoded=$encoded\n";
+
+ok $encoded;
+
+my $decoded = APR::Base64::decode($encoded);
+
+ok $decoded eq $bytes;
+
+$p->clear;
+
+for (1..9) {
+ my $desc = APR::Signal::get_description($_);
+ #print "$_ => $desc\n";
+}
+
+ok 1;
+
+$p->destroy; #XXX
diff --git a/2_0_13/xs/APR/Base64/APR__Base64.h b/2_0_13/xs/APR/Base64/APR__Base64.h
new file mode 100644
index 0000000..8ed26f9
--- /dev/null
+++ b/2_0_13/xs/APR/Base64/APR__Base64.h
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* apr_base64_encode_len and apr_base64_encode_binary give length that
+ * includes the terminating '\0' */
+#define mpxs_APR__Base64_encode_len(len) (apr_base64_encode_len(len) - 1)
+
+static MP_INLINE void mpxs_apr_base64_encode(pTHX_ SV *sv, SV *arg)
+{
+ STRLEN len;
+ int encoded_len;
+ unsigned char *data = (unsigned char *)SvPV(arg, len);
+ mpxs_sv_grow(sv, apr_base64_encode_len(len) - 1);
+ encoded_len = apr_base64_encode_binary(SvPVX(sv), data, len);
+ mpxs_sv_cur_set(sv, encoded_len - 1);
+}
+
+static MP_INLINE void mpxs_apr_base64_decode(pTHX_ SV *sv, SV *arg)
+{
+ STRLEN len;
+ int decoded_len;
+ char *data = SvPV(arg, len);
+ mpxs_sv_grow(sv, apr_base64_decode_len(data));
+ decoded_len = apr_base64_decode_binary((unsigned char *)SvPVX(sv), data);
+ mpxs_sv_cur_set(sv, decoded_len);
+}
+
+MP_STATIC XS(MPXS_apr_base64_encode)
+{
+ dXSARGS;
+
+ mpxs_usage_items_1("data");
+
+ mpxs_set_targ(mpxs_apr_base64_encode, ST(0));
+}
+
+MP_STATIC XS(MPXS_apr_base64_decode)
+{
+ dXSARGS;
+
+ mpxs_usage_items_1("data");
+
+ mpxs_set_targ(mpxs_apr_base64_decode, ST(0));
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Brigade/APR__Brigade.h b/2_0_13/xs/APR/Brigade/APR__Brigade.h
new file mode 100644
index 0000000..15181fd
--- /dev/null
+++ b/2_0_13/xs/APR/Brigade/APR__Brigade.h
@@ -0,0 +1,180 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+void mpxs_APR__Brigade_cleanup(apr_bucket_brigade *brigade)
+{
+ /* apr has a broken prototype (passing 'void *' instead of
+ * 'apr_bucket_brigade *', so use a wrapper here */
+ apr_brigade_cleanup(brigade);
+}
+
+static MP_INLINE
+SV *mpxs_apr_brigade_create(pTHX_ SV *CLASS, SV *p_sv,
+ apr_bucket_alloc_t *ba)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_bucket_brigade *bb = apr_brigade_create(p, ba);
+ SV *bb_sv = sv_setref_pv(newSV(0), "APR::Brigade", (void*)bb);
+ mpxs_add_pool_magic(bb_sv, p_sv);
+ return bb_sv;
+}
+
+#define get_brigade(brigade, fetch) \
+(fetch(brigade) == APR_BRIGADE_SENTINEL(brigade) ? \
+ NULL : fetch(brigade))
+
+static MP_INLINE
+apr_bucket *mpxs_APR__Brigade_first(apr_bucket_brigade *brigade)
+{
+ return get_brigade(brigade, APR_BRIGADE_FIRST);
+}
+
+static MP_INLINE
+apr_bucket *mpxs_APR__Brigade_last(apr_bucket_brigade *brigade)
+{
+ return get_brigade(brigade, APR_BRIGADE_LAST);
+}
+
+#define get_bucket(brigade, bucket, fetch) \
+(fetch(bucket) == APR_BRIGADE_SENTINEL(brigade) ? \
+ NULL : fetch(bucket))
+
+static MP_INLINE
+apr_bucket *mpxs_APR__Brigade_next(apr_bucket_brigade *brigade,
+ apr_bucket *bucket)
+{
+ return get_bucket(brigade, bucket, APR_BUCKET_NEXT);
+}
+
+static MP_INLINE
+apr_bucket *mpxs_APR__Brigade_prev(apr_bucket_brigade *brigade,
+ apr_bucket *bucket)
+{
+ return get_bucket(brigade, bucket, APR_BUCKET_PREV);
+}
+
+static MP_INLINE
+void mpxs_APR__Brigade_insert_tail(apr_bucket_brigade *brigade,
+ apr_bucket *bucket)
+{
+ APR_BRIGADE_INSERT_TAIL(brigade, bucket);
+}
+
+static MP_INLINE
+void mpxs_APR__Brigade_insert_head(apr_bucket_brigade *brigade,
+ apr_bucket *bucket)
+{
+ APR_BRIGADE_INSERT_HEAD(brigade, bucket);
+}
+
+static MP_INLINE
+void mpxs_APR__Brigade_concat(apr_bucket_brigade *a,
+ apr_bucket_brigade *b)
+{
+ APR_BRIGADE_CONCAT(a, b);
+}
+
+static MP_INLINE
+int mpxs_APR__Brigade_is_empty(apr_bucket_brigade *brigade)
+{
+ return APR_BRIGADE_EMPTY(brigade);
+}
+
+static MP_INLINE
+apr_pool_t *mpxs_APR__Brigade_pool(apr_bucket_brigade *brigade)
+{
+ /* eesh, it's r->pool, and c->pool, but bb->p
+ * let's make Perl consistent, otherwise this could be autogenerated
+ */
+
+ return brigade->p;
+}
+
+static MP_INLINE
+SV *mpxs_APR__Brigade_length(pTHX_ apr_bucket_brigade *bb,
+ int read_all)
+{
+ apr_off_t length;
+
+ apr_status_t rv = apr_brigade_length(bb, read_all, &length);
+
+ /* XXX - we're deviating from the API here a bit in order to
+ * make it more perlish - returning the length instead of
+ * the return code. maybe that's not such a good idea, though...
+ */
+ if (rv == APR_SUCCESS) {
+ return newSViv((int)length);
+ }
+
+ return &PL_sv_undef;
+}
+
+#define mp_xs_sv2_bb mp_xs_sv2_APR__Brigade
+
+static MP_INLINE
+apr_size_t mpxs_APR__Brigade_flatten(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+
+ apr_bucket_brigade *bb;
+ apr_size_t wanted;
+ apr_status_t rc;
+ SV *buffer;
+
+ mpxs_usage_va_2(bb, buffer, "$bb->flatten($buf, [$wanted])");
+
+ if (items > 2) {
+ /* APR::Brigade->flatten($wanted); */
+ wanted = SvIV(*MARK);
+ }
+ else {
+ /* APR::Brigade->flatten(); */
+ /* can't use pflatten, because we can't realloc() memory
+ * allocated by pflatten. and we need to append '\0' to it in
+ * SvPVX. so we copy pflatten's guts here.
+ */
+ apr_off_t actual;
+ apr_brigade_length(bb, 1, &actual);
+ wanted = (apr_size_t)actual;
+ }
+
+ (void)SvUPGRADE(buffer, SVt_PV);
+ mpxs_sv_grow(buffer, wanted);
+
+ rc = apr_brigade_flatten(bb, SvPVX(buffer), &wanted);
+ if (!(rc == APR_SUCCESS || rc == APR_EOF)) {
+ modperl_croak(aTHX_ rc, "APR::Brigade::flatten");
+ }
+
+ mpxs_sv_cur_set(buffer, wanted);
+ SvTAINTED_on(buffer);
+
+ return wanted;
+}
+
+static MP_INLINE
+void mpxs_APR__Brigade_destroy(pTHX_ apr_bucket_brigade *bb)
+{
+ MP_RUN_CROAK(apr_brigade_destroy(bb), "APR::Brigade::destroy");
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Bucket/APR__Bucket.h b/2_0_13/xs/APR/Bucket/APR__Bucket.h
new file mode 100644
index 0000000..6c09c75
--- /dev/null
+++ b/2_0_13/xs/APR/Bucket/APR__Bucket.h
@@ -0,0 +1,131 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_bucket.h"
+
+#define mpxs_APR__Bucket_delete apr_bucket_delete
+#define mpxs_APR__Bucket_destroy apr_bucket_destroy
+
+static apr_bucket *mpxs_APR__Bucket_new(pTHX_ SV *classname, apr_bucket_alloc_t *list,
+ SV *sv, apr_off_t offset, apr_size_t len)
+{
+
+ apr_size_t full_len;
+
+ if (sv == (SV *)NULL) {
+ sv = newSV(0);
+ (void)SvUPGRADE(sv, SVt_PV);
+ }
+
+ (void)SvPV(sv, full_len);
+
+ if (len) {
+ if (len > full_len - offset) {
+ Perl_croak(aTHX_ "APR::Bucket::new: the length argument can't be"
+ " bigger than the total buffer length minus offset");
+ }
+ }
+ else {
+ len = full_len - offset;
+ }
+
+ return modperl_bucket_sv_create(aTHX_ list, sv, offset, len);
+}
+
+static MP_INLINE
+apr_size_t mpxs_APR__Bucket_read(pTHX_
+ apr_bucket *bucket,
+ SV *buffer,
+ apr_read_type_e block)
+{
+ apr_size_t len;
+ const char *str;
+ apr_status_t rc = apr_bucket_read(bucket, &str, &len, block);
+
+ if (!(rc == APR_SUCCESS || rc == APR_EOF)) {
+ modperl_croak(aTHX_ rc, "APR::Bucket::read");
+ }
+
+ if (len) {
+ sv_setpvn(buffer, str, len);
+ }
+ else {
+ sv_setpvn(buffer, "", 0);
+ }
+
+ /* must run any set magic */
+ SvSETMAGIC(buffer);
+
+ SvTAINTED_on(buffer);
+
+ return len;
+}
+
+static MP_INLINE int mpxs_APR__Bucket_is_eos(apr_bucket *bucket)
+{
+ return APR_BUCKET_IS_EOS(bucket);
+}
+
+static MP_INLINE int mpxs_APR__Bucket_is_flush(apr_bucket *bucket)
+{
+ return APR_BUCKET_IS_FLUSH(bucket);
+}
+
+static MP_INLINE void mpxs_APR__Bucket_insert_before(apr_bucket *a,
+ apr_bucket *b)
+{
+ APR_BUCKET_INSERT_BEFORE(a, b);
+}
+
+static MP_INLINE void mpxs_APR__Bucket_insert_after(apr_bucket *a,
+ apr_bucket *b)
+{
+ APR_BUCKET_INSERT_AFTER(a, b);
+}
+
+static MP_INLINE void mpxs_APR__Bucket_remove(apr_bucket *bucket)
+{
+ APR_BUCKET_REMOVE(bucket);
+}
+
+static MP_INLINE
+apr_status_t mpxs_APR__Bucket_setaside(pTHX_ SV *b_sv, SV *p_sv)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_bucket *b = mp_xs_sv2_APR__Bucket(b_sv);
+ apr_status_t rc = apr_bucket_setaside(b, p);
+
+ /* if users don't bother to check the success, do it on their
+ * behalf */
+ if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
+ modperl_croak(aTHX_ rc, "APR::Bucket::setaside");
+ }
+
+ /* No need to call mpxs_add_pool_magic(b_sv, p_sv); since
+ * pool_bucket_cleanup is called by apr_bucket_pool_make (called
+ * by modperl_bucket_sv_setaside) if the pool goes out of scope,
+ * copying the data to the heap.
+ */
+
+ return rc;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/BucketAlloc/APR__BucketAlloc.h b/2_0_13/xs/APR/BucketAlloc/APR__BucketAlloc.h
new file mode 100644
index 0000000..bfb2a19
--- /dev/null
+++ b/2_0_13/xs/APR/BucketAlloc/APR__BucketAlloc.h
@@ -0,0 +1,36 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_bucket.h"
+
+#define mpxs_APR__BucketAlloc_destroy apr_bucket_alloc_destroy
+
+static MP_INLINE
+SV *mpxs_APR__BucketAlloc_new(pTHX_ SV *CLASS, SV *p_sv)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
+ SV *ba_sv = sv_setref_pv(newSV(0), "APR::BucketAlloc", (void*)ba);
+ mpxs_add_pool_magic(ba_sv, p_sv);
+ return ba_sv;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Const/Const.pm b/2_0_13/xs/APR/Const/Const.pm
new file mode 100644
index 0000000..cb264f6
--- /dev/null
+++ b/2_0_13/xs/APR/Const/Const.pm
@@ -0,0 +1,28 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package APR::Const;
+
+use ModPerl::Const ();
+use APR ();
+use XSLoader ();
+
+our $VERSION = '0.009000';
+our @ISA = qw(ModPerl::Const);
+
+XSLoader::load(__PACKAGE__, $VERSION);
+
+1;
diff --git a/2_0_13/xs/APR/Const/Const.xs b/2_0_13/xs/APR/Const/Const.xs
new file mode 100644
index 0000000..9d457c3
--- /dev/null
+++ b/2_0_13/xs/APR/Const/Const.xs
@@ -0,0 +1,26 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+#include "modperl_const.h"
+
+MODULE = APR::Const PACKAGE = APR::Const
+
+PROTOTYPES: disable
+
+BOOT:
+ MP_newModPerlConstXS("APR");
+
diff --git a/2_0_13/xs/APR/Const/Makefile.PL b/2_0_13/xs/APR/Const/Makefile.PL
new file mode 100644
index 0000000..c567a34
--- /dev/null
+++ b/2_0_13/xs/APR/Const/Makefile.PL
@@ -0,0 +1,15 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+use Apache2::Build;
+
+my $build = Apache2::Build->build_config();
+my $ccopts = $build->ccopts;
+
+# avoid referencing &perl_module outside of mod_perl
+$ccopts .= ' -DMP_IN_XS';
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => 'APR::Const',
+ VERSION_FROM => 'Const.pm',
+ CCFLAGS => $ccopts,
+);
diff --git a/2_0_13/xs/APR/Error/APR__Error.h b/2_0_13/xs/APR/Error/APR__Error.h
new file mode 100644
index 0000000..c7dafd9
--- /dev/null
+++ b/2_0_13/xs/APR/Error/APR__Error.h
@@ -0,0 +1,24 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mpxs_APR__Error_strerror(rc) modperl_error_strerror(aTHX_ rc)
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Error/Error_pm b/2_0_13/xs/APR/Error/Error_pm
new file mode 100644
index 0000000..9cb6081
--- /dev/null
+++ b/2_0_13/xs/APR/Error/Error_pm
@@ -0,0 +1,69 @@
+require Carp;
+require Carp::Heavy;
+
+use APR::Util ();
+
+use overload
+ nomethod => \&fatal,
+ 'bool' => \&str,
+ '==' => \&num_cmp,
+ '!=' => \&num_cmp_not,
+ '0+' => \&num,
+ '""' => \&str;
+
+sub fatal { die __PACKAGE__ . ": Can't handle '$_[3]'" }
+
+# normally the object is created on the C side, but if you want to
+# create one from Perl, you can. just pass a hash with args:
+# rc, file, line, func
+sub new {
+ my $class = shift;
+ my %args = @_;
+ bless \%args, $class;
+}
+
+#
+# - even though most of the time the error id is not useful to the end
+# users, developers may need to know it. For example in case of a
+# non-english user locale setting, the error string could be
+# incomprehensible to a developer, but by having the error id it's
+# possible to find the english equivalent
+# - the filename and line number are needed because perl doesn't
+# provide that info when exception objects are involved
+sub str {
+ return sprintf "%s: (%d) %s at %s line %d", $_[0]->{func},
+ $_[0]->{rc}, APR::Error::strerror($_[0]->{rc}),
+ $_[0]->{file}, $_[0]->{line};
+}
+
+sub num { $_[0]->{rc} }
+
+sub num_cmp { $_[0]->{rc} == $_[1] }
+sub num_cmp_not { $_[0]->{rc} != $_[1] }
+
+# skip the wrappers from this package from the long callers trace
+$Carp::CarpInternal{+__PACKAGE__}++;
+
+# XXX: Carp::(confess|cluck) see no calls stack when Perl_croak is
+# called with (char *)NULL (which is the way exception objects are
+# returned), so we fixup it here (doesn't quite work for croak
+# caller).
+sub cluck {
+ if (ref $_[0] eq __PACKAGE__) {
+ Carp::cluck("$_[0]->{func}: ($_[0]->{rc}) " .
+ APR::Error::strerror($_[0]->{rc}));
+ }
+ else {
+ &Carp::cluck;
+ }
+}
+
+sub confess {
+ if (ref $_[0] eq __PACKAGE__) {
+ Carp::confess("$_[0]->{func}: ($_[0]->{rc}) " .
+ APR::Error::strerror($_[0]->{rc}));
+ }
+ else {
+ &Carp::confess;
+ }
+}
diff --git a/2_0_13/xs/APR/Finfo/APR__Finfo.h b/2_0_13/xs/APR/Finfo/APR__Finfo.h
new file mode 100644
index 0000000..36843ab
--- /dev/null
+++ b/2_0_13/xs/APR/Finfo/APR__Finfo.h
@@ -0,0 +1,39 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+SV *mpxs_APR__Finfo_stat(pTHX_ const char *fname, apr_int32_t wanted,
+ SV *p_sv)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_finfo_t *finfo = (apr_finfo_t *)apr_pcalloc(p, sizeof(apr_finfo_t));
+ SV *finfo_sv;
+
+ MP_RUN_CROAK(apr_stat(finfo, fname, wanted, p),
+ "APR::Finfo::stat");
+
+ finfo_sv = sv_setref_pv(newSV(0), "APR::Finfo", (void*)finfo);
+ mpxs_add_pool_magic(finfo_sv, p_sv);
+
+ return finfo_sv;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/IpSubnet/APR__IpSubnet.h b/2_0_13/xs/APR/IpSubnet/APR__IpSubnet.h
new file mode 100644
index 0000000..c2d6793
--- /dev/null
+++ b/2_0_13/xs/APR/IpSubnet/APR__IpSubnet.h
@@ -0,0 +1,37 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+SV *mpxs_apr_ipsubnet_create(pTHX_ SV *classname, SV *p_sv,
+ const char *ipstr,
+ const char *mask_or_numbits)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_ipsubnet_t *ipsub = NULL;
+ SV *ipsub_sv;
+ MP_RUN_CROAK(apr_ipsubnet_create(&ipsub, ipstr, mask_or_numbits, p),
+ "APR::IpSubnet::new");
+ ipsub_sv = sv_setref_pv(newSV(0), "APR::IpSubnet", (void*)ipsub);
+ mpxs_add_pool_magic(ipsub_sv, p_sv);
+ return ipsub_sv;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Lock/APR__Lock.h b/2_0_13/xs/APR/Lock/APR__Lock.h
new file mode 100644
index 0000000..1054331
--- /dev/null
+++ b/2_0_13/xs/APR/Lock/APR__Lock.h
@@ -0,0 +1,22 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Makefile.PL b/2_0_13/xs/APR/Makefile.PL
new file mode 100644
index 0000000..1302942
--- /dev/null
+++ b/2_0_13/xs/APR/Makefile.PL
@@ -0,0 +1,7 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => "APR_build",
+ VERSION => '0.01'
+);
diff --git a/2_0_13/xs/APR/OS/APR__OS.h b/2_0_13/xs/APR/OS/APR__OS.h
new file mode 100644
index 0000000..5cd6f59
--- /dev/null
+++ b/2_0_13/xs/APR/OS/APR__OS.h
@@ -0,0 +1,31 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE unsigned long mpxs_APR__OS_current_thread_id(pTHX)
+{
+#if APR_HAS_THREADS
+ return (unsigned long)apr_os_thread_current();
+#else
+ return 0;
+#endif
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/PerlIO/Makefile.PL b/2_0_13/xs/APR/PerlIO/Makefile.PL
new file mode 100644
index 0000000..ca102bb
--- /dev/null
+++ b/2_0_13/xs/APR/PerlIO/Makefile.PL
@@ -0,0 +1,37 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+use Config;
+use Apache2::Build;
+use Apache::TestTrace;
+my $build = Apache2::Build->build_config();
+
+my $ccopts = $build->ccopts;
+
+# when uselargefiles is on, -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+# are needed to get the right 'Off_t', without which perlio compiled
+# with Off_t as 'long long int', doesn't quite work with apr_perlio.c
+# compiled with Off_t as 'long int'
+#
+# On the other handl if apr is built without large files support, we
+# have binary compatibility problems, if we try to build mod_perl with
+# -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+#
+# XXX: it seems that enabling these flags only for apr_perlio/PerlIO
+# seems to do the trick
+if ($build->has_large_files_conflict) {
+ $ccopts .= $Config{uselargefiles}
+ ? ' ' . $Config{ccflags_uselargefiles}
+ : '';
+}
+
+# avoid referencing &perl_module outside of mod_perl
+$ccopts .= ' -DMP_IN_XS';
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => 'APR::PerlIO',
+ VERSION_FROM => 'PerlIO.pm',
+ CCFLAGS => $ccopts,
+ OBJECT => 'PerlIO.o modperl_apr_perlio.o'
+);
+
diff --git a/2_0_13/xs/APR/PerlIO/PerlIO.pm b/2_0_13/xs/APR/PerlIO/PerlIO.pm
new file mode 100644
index 0000000..72a6330
--- /dev/null
+++ b/2_0_13/xs/APR/PerlIO/PerlIO.pm
@@ -0,0 +1,32 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package APR::PerlIO;
+
+require 5.006001;
+
+our $VERSION = '0.009000';
+
+# The PerlIO layer is available only since 5.8.0 (5.7.2@13534)
+use Config;
+use constant PERLIO_LAYERS_ARE_ENABLED => $Config{useperlio} && $] >= 5.007003;
+
+use APR ();
+use APR::XSLoader ();
+APR::XSLoader::load __PACKAGE__;
+
+
+1;
diff --git a/2_0_13/xs/APR/PerlIO/PerlIO.xs b/2_0_13/xs/APR/PerlIO/PerlIO.xs
new file mode 100644
index 0000000..f833017
--- /dev/null
+++ b/2_0_13/xs/APR/PerlIO/PerlIO.xs
@@ -0,0 +1,25 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+#include "modperl_apr_perlio.h"
+
+MODULE = APR::PerlIO PACKAGE = APR::PerlIO
+
+PROTOTYPES: disabled
+
+BOOT:
+ modperl_apr_perlio_init(aTHX);
diff --git a/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.c b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.c
new file mode 100644
index 0000000..e8c93a4
--- /dev/null
+++ b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.c
@@ -0,0 +1,633 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_largefiles.h"
+
+#include "mod_perl.h"
+#include "modperl_apr_perlio.h"
+
+#if defined(PERLIO_LAYERS) && defined(PERLIO_K_MULTIARG) /* 5.7.2+ */
+
+/**********************************************************************
+ * The PerlIO APR layer.
+ * The PerlIO API is documented in perliol.pod.
+ **********************************************************************/
+
+/*
+ * APR::PerlIO implements a PerlIO layer using apr_file_io as the core.
+ */
+
+/*
+ * XXX: Since we cannot snoop on the internal apr_file_io buffer
+ * currently the IO is not buffered on the Perl side so every read
+ * requests a char at a time, which is slow. Consider copying the
+ * relevant code from PerlIOBuf to implement our own buffer, similar
+ * to what PerlIOBuf does or push :perlio layer on top of this layer
+ */
+
+typedef struct {
+ struct _PerlIO base;
+ apr_file_t *file;
+ apr_pool_t *pool;
+} PerlIOAPR;
+
+static IV PerlIOAPR_pushed(pTHX_ PerlIO *f, const char *mode,
+ SV *arg, PerlIO_funcs *tab)
+{
+ IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
+ if (*PerlIONext(f)) {
+ /* XXX: not sure if we can do anything here, but see
+ * PerlIOUnix_pushed for things that it does
+ */
+ }
+ return code;
+}
+
+static PerlIO *PerlIOAPR_open(pTHX_ PerlIO_funcs *self,
+ PerlIO_list_t *layers, IV n,
+ const char *mode, int fd, int imode,
+ int perm, PerlIO *f, int narg, SV **args)
+{
+ SV *arg = (narg > 0) ? *args : PerlIOArg;
+ PerlIOAPR *st;
+ const char *path;
+ apr_int32_t apr_flag;
+ apr_status_t rc;
+ SV *sv;
+
+ if (!(SvROK(arg) || SvPOK(arg))) {
+ return NULL;
+ }
+
+ /* XXX: why passing only SV* for arg, check this out in PerlIO_push */
+ if (!f) {
+ f = PerlIO_push(aTHX_ PerlIO_allocate(aTHX), self, mode, arg);
+ }
+ else {
+ f = PerlIO_push(aTHX_ f, self, mode, arg);
+ }
+
+ /* grab the last arg as a filepath */
+ path = (const char *)SvPV_nolen(args[narg-2]);
+
+ switch (*mode) {
+ case 'a':
+ apr_flag = APR_APPEND | APR_CREATE;
+ break;
+ case 'w':
+ apr_flag = APR_WRITE | APR_CREATE | APR_TRUNCATE;
+ break;
+ case 'r':
+ apr_flag = APR_READ;
+ break;
+ default:
+ Perl_croak(aTHX_ "unknown open mode: %s", mode);
+ }
+
+ /* APR_BINARY: we always do binary read and PerlIO is supposed
+ * to handle :crlf if any (by pushing this layer at
+ * open().
+ * APR_BUFFERED: XXX, not sure if it'll be needed if we will push
+ * :perlio (== PerlIOBuf) layer on top
+ */
+ apr_flag |= APR_BUFFERED | APR_BINARY;
+
+ st = PerlIOSelf(f, PerlIOAPR);
+
+ /* XXX: can't reuse a wrapper mp_xs_sv2_APR__Pool */
+ /* XXX: should probably add checks on pool validity in all other callbacks */
+ sv = args[narg-1];
+ if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) {
+ st->pool = INT2PTR(apr_pool_t *, SvIV((SV*)SvRV(sv)));
+ }
+ else {
+ Perl_croak(aTHX_ "argument is not a blessed reference "
+ "(expecting an APR::Pool derived object)");
+ }
+
+ rc = apr_file_open(&st->file, path, apr_flag, APR_OS_DEFAULT, st->pool);
+
+ MP_TRACE_o(MP_FUNC, "obj=0x%lx, file=0x%lx, name=%s, rc=%d",
+ (unsigned long)f, (unsigned long)st->file,
+ path ? path : "(UNKNOWN)", rc);
+
+ if (rc != APR_SUCCESS) {
+ /* it just so happens that since $! is tied to errno, we get
+ * it set right via the system call that apr_file_open has
+ * performed internally, no need to do anything special */
+ PerlIO_pop(aTHX_ f);
+ return NULL;
+ }
+
+ PerlIOBase(f)->flags |= PERLIO_F_OPEN;
+ return f;
+}
+
+static IV PerlIOAPR_fileno(pTHX_ PerlIO *f)
+{
+ /* apr_file_t* is an opaque struct, so fileno is not available.
+ * -1 in this case indicates that the layer cannot provide fileno
+ */
+ return -1;
+}
+
+static PerlIO *PerlIOAPR_dup(pTHX_ PerlIO *f, PerlIO *o,
+ CLONE_PARAMS *param, int flags)
+{
+ apr_status_t rc;
+
+ if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
+ PerlIOAPR *fst = PerlIOSelf(f, PerlIOAPR);
+ PerlIOAPR *ost = PerlIOSelf(o, PerlIOAPR);
+
+ rc = apr_file_dup(&fst->file, ost->file, ost->pool);
+
+ MP_TRACE_o(MP_FUNC, "obj=0x%lx, "
+ "file=0x%lx => 0x%lx, rc=%d",
+ (unsigned long)f, (unsigned long)ost->file,
+ (unsigned long)fst->file, rc);
+
+ if (rc == APR_SUCCESS) {
+ fst->pool = ost->pool;
+ return f;
+ }
+ }
+
+ return NULL;
+}
+
+static SSize_t PerlIOAPR_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_status_t rc;
+
+ rc = apr_file_read(st->file, vbuf, &count);
+
+ MP_TRACE_o(MP_FUNC, "%db [%s]", (int)count,
+ MP_TRACE_STR_TRUNC(st->pool, (char *)vbuf, (int)count));
+
+ if (rc == APR_EOF) {
+ PerlIOBase(f)->flags |= PERLIO_F_EOF;
+ return count;
+ }
+ else if (rc != APR_SUCCESS) {
+ modperl_croak(aTHX_ rc, "APR::PerlIO::read");
+ }
+
+ return count;
+}
+
+static SSize_t PerlIOAPR_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_status_t rc;
+
+ MP_TRACE_o(MP_FUNC, "%db [%s]", (int)count,
+ MP_TRACE_STR_TRUNC(st->pool, (char *)vbuf, (int)count));
+
+ rc = apr_file_write(st->file, vbuf, &count);
+ if (rc == APR_SUCCESS) {
+ return (SSize_t) count;
+ }
+
+ PerlIOBase(f)->flags |= PERLIO_F_ERROR;
+ return (SSize_t) -1;
+}
+
+static IV PerlIOAPR_flush(pTHX_ PerlIO *f)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_status_t rc;
+
+ rc = apr_file_flush(st->file);
+ if (rc == APR_SUCCESS) {
+ return 0;
+ }
+
+ PerlIOBase(f)->flags |= PERLIO_F_ERROR;
+ return -1;
+}
+
+static IV PerlIOAPR_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_seek_where_t where;
+ apr_status_t rc;
+ apr_off_t seek_offset = 0;
+
+#ifdef MP_LARGE_FILES_CONFLICT
+ if (offset != 0) {
+ Perl_croak(aTHX_ "PerlIO::APR::seek with non-zero offset"
+ "is not supported with Perl built w/ -Duselargefiles"
+ " and APR w/o largefiles support");
+ }
+#else
+ seek_offset = offset;
+#endif
+
+ /* Flush the fill buffer */
+ if (PerlIO_flush(f) != 0) {
+ return -1;
+ }
+
+ switch(whence) {
+ case 0:
+ where = APR_SET;
+ break;
+ case 1:
+ where = APR_CUR;
+ break;
+ case 2:
+ where = APR_END;
+ break;
+ default:
+ Perl_croak(aTHX_ "unknown whence mode: %d", whence);
+ }
+
+ rc = apr_file_seek(st->file, where, &seek_offset);
+ if (rc == APR_SUCCESS) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static Off_t PerlIOAPR_tell(pTHX_ PerlIO *f)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_off_t offset = 0;
+ apr_status_t rc;
+
+ rc = apr_file_seek(st->file, APR_CUR, &offset);
+ if (rc == APR_SUCCESS) {
+ return (Off_t) offset;
+ }
+
+ return (Off_t) -1;
+}
+
+static IV PerlIOAPR_close(pTHX_ PerlIO *f)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ IV code = PerlIOBase_close(aTHX_ f);
+ apr_status_t rc;
+
+#ifdef MP_TRACE
+ const char *new_path = NULL;
+ apr_os_file_t os_file;
+
+#ifdef PERL_PHASE_DESTRUCT
+ if (PL_phase != PERL_PHASE_DESTRUCT) {
+#else
+ if (!PL_dirty) {
+#endif
+ /* if this is called during perl_destruct we are in trouble */
+ apr_file_name_get(&new_path, st->file);
+ }
+
+ rc = apr_os_file_get(&os_file, st->file);
+ if (rc != APR_SUCCESS) {
+ Perl_croak(aTHX_ "filedes retrieval failed!");
+ }
+
+ MP_TRACE_o(MP_FUNC, "obj=0x%lx, file=0x%lx, fd=%d, name=%s",
+ (unsigned long)f, (unsigned long)st->file, os_file,
+ new_path ? new_path : "(UNKNOWN)");
+#endif
+
+#ifdef PERL_PHASE_DESTRUCT
+ if (PL_phase == PERL_PHASE_DESTRUCT) {
+#else
+ if (PL_dirty) {
+#endif
+ /* there should not be any PerlIOAPR handles open
+ * during perl_destruct
+ */
+ Perl_warn(aTHX_ "leaked PerlIOAPR handle 0x%lx",
+ (unsigned long)f);
+ return -1;
+ }
+
+ rc = apr_file_flush(st->file);
+ if (rc != APR_SUCCESS) {
+ return -1;
+ }
+
+ rc = apr_file_close(st->file);
+ if (rc != APR_SUCCESS) {
+ return -1;
+ }
+
+ return code;
+}
+
+#if 0 /* we may use it if the buffering will be done at this layer */
+
+static IV PerlIOAPR_fill(pTHX_ PerlIO *f)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_status_t rc;
+ SSize_t avail;
+ Size_t count = st->base.bufsiz;
+
+ if (!st->base.buf) {
+ PerlIO_get_base(f); /* allocate via vtable */
+ }
+
+ MP_TRACE_o(MP_FUNC, "asked to fill %d chars", count);
+
+ rc = apr_file_read(st->file, st->base.ptr, &count);
+ if (rc != APR_SUCCESS) {
+ PerlIOBase(f)->flags |= PERLIO_F_ERROR;
+ return -1;
+ }
+
+ MP_TRACE_o(MP_FUNC, "got to fill %d chars", count);
+
+ avail = count; /* apr_file_read() sets how many chars were read in count */
+ if (avail <= 0) {
+ if (avail == 0) {
+ PerlIOBase(f)->flags |= PERLIO_F_EOF;
+ }
+ else {
+ PerlIOBase(f)->flags |= PERLIO_F_ERROR;
+ }
+
+ return -1;
+ }
+ st->base.end = st->base.buf + avail;
+
+ /* indicate that the buffer this layer currently holds unconsumed
+ data read from layer below. */
+ PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
+
+ return 0;
+}
+
+#endif
+
+static IV PerlIOAPR_eof(pTHX_ PerlIO *f)
+{
+ PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+ apr_status_t rc;
+
+ rc = apr_file_eof(st->file);
+ switch (rc) {
+ case APR_EOF:
+ return 1;
+ default:
+ return 0;
+ }
+
+ return -1;
+}
+
+/* 5.8.0 doesn't export PerlIOBase_noop_fail, so we duplicate it here */
+static IV PerlIOAPR_noop_fail(pTHX_ PerlIO *f)
+{
+ return -1;
+}
+
+static PerlIO_funcs PerlIO_APR = {
+ sizeof(PerlIO_funcs),
+ "APR",
+ sizeof(PerlIOAPR),
+ PERLIO_K_MULTIARG | PERLIO_K_RAW,
+ PerlIOAPR_pushed,
+ PerlIOBase_popped,
+ PerlIOAPR_open,
+ PerlIOBase_binmode, /* binmode() is handled by :crlf */
+ NULL, /* no getarg needed */
+ PerlIOAPR_fileno,
+ PerlIOAPR_dup,
+ PerlIOAPR_read,
+ PerlIOBase_unread,
+ PerlIOAPR_write,
+ PerlIOAPR_seek,
+ PerlIOAPR_tell,
+ PerlIOAPR_close,
+ PerlIOAPR_flush, /* flush */
+ PerlIOAPR_noop_fail, /* fill */
+ PerlIOAPR_eof,
+ PerlIOBase_error,
+ PerlIOBase_clearerr,
+ PerlIOBase_setlinebuf,
+ NULL, /* get_base */
+ NULL, /* get_bufsiz */
+ NULL, /* get_ptr */
+ NULL, /* get_cnt */
+ NULL, /* set_ptrcnt */
+};
+
+void modperl_apr_perlio_init(pTHX)
+{
+ APR_REGISTER_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_PerlIO);
+ APR_REGISTER_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_glob);
+
+ PerlIO_define_layer(aTHX_ &PerlIO_APR);
+}
+
+
+/* ***** End of PerlIOAPR tab ***** */
+
+
+/* ***** PerlIO <=> apr_file_t helper functions ***** */
+
+PerlIO *modperl_apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file,
+ apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type)
+{
+ char *mode;
+ const char *layers = ":APR";
+ PerlIOAPR *st;
+ PerlIO *f = PerlIO_allocate(aTHX);
+
+ if (!f) {
+ Perl_croak(aTHX_ "Failed to allocate PerlIO struct");
+ }
+
+ switch (type) {
+ case MODPERL_APR_PERLIO_HOOK_WRITE:
+ mode = "w";
+ break;
+ case MODPERL_APR_PERLIO_HOOK_READ:
+ mode = "r";
+ break;
+ default:
+ Perl_croak(aTHX_ "unknown MODPERL_APR_PERLIO type: %d", type);
+ };
+
+ PerlIO_apply_layers(aTHX_ f, mode, layers);
+ if (!f) {
+ Perl_croak(aTHX_ "Failed to apply the ':APR' layer");
+ }
+
+ st = PerlIOSelf(f, PerlIOAPR);
+
+#ifdef MP_TRACE
+ {
+ apr_status_t rc;
+ apr_os_file_t os_file;
+
+ /* convert to the OS representation of file */
+ rc = apr_os_file_get(&os_file, file);
+ if (rc != APR_SUCCESS) {
+ croak("filedes retrieval failed!");
+ }
+
+ MP_TRACE_o(MP_FUNC, "converting to PerlIO fd %d, mode '%s'",
+ os_file, mode);
+ }
+#endif
+
+ st->pool = pool;
+ st->file = file;
+ PerlIOBase(f)->flags |= PERLIO_F_OPEN;
+
+ return f;
+}
+
+static SV *modperl_apr_perlio_PerlIO_to_glob(pTHX_ PerlIO *pio,
+ modperl_apr_perlio_hook_e type)
+{
+ SV *retval = modperl_perl_gensym(aTHX_ "APR::PerlIO");
+ GV *gv = (GV*)SvRV(retval);
+
+ gv_IOadd(gv);
+
+ switch (type) {
+ case MODPERL_APR_PERLIO_HOOK_WRITE:
+ /* if IoIFP() is not assigned to it'll be never closed, see
+ * Perl_io_close() */
+ IoIFP(GvIOp(gv)) = IoOFP(GvIOp(gv)) = pio;
+ IoFLAGS(GvIOp(gv)) |= IOf_FLUSH;
+ IoTYPE(GvIOp(gv)) = IoTYPE_WRONLY;
+ break;
+ case MODPERL_APR_PERLIO_HOOK_READ:
+ IoIFP(GvIOp(gv)) = pio;
+ IoTYPE(GvIOp(gv)) = IoTYPE_RDONLY;
+ break;
+ };
+
+ return sv_2mortal(retval);
+}
+
+SV *modperl_apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file,
+ apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type)
+{
+ return modperl_apr_perlio_PerlIO_to_glob(aTHX_
+ modperl_apr_perlio_apr_file_to_PerlIO(aTHX_ file, pool, type),
+ type);
+}
+
+#else /* defined(PERLIO_LAYERS) (5.6.x) */
+
+#ifdef USE_PERLIO /* 5.6.x + -Duseperlio */
+#define MP_IO_TYPE PerlIO
+#else
+#define MP_IO_TYPE FILE
+#endif
+
+static MP_IO_TYPE *modperl_apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file,
+ modperl_apr_perlio_hook_e type)
+{
+ MP_IO_TYPE *retval;
+ char *mode;
+ int fd;
+ apr_os_file_t os_file;
+ apr_status_t rc;
+
+ switch (type) {
+ case MODPERL_APR_PERLIO_HOOK_WRITE:
+ mode = "w";
+ break;
+ case MODPERL_APR_PERLIO_HOOK_READ:
+ mode = "r";
+ break;
+ };
+
+ /* convert to the OS representation of file */
+ rc = apr_os_file_get(&os_file, file);
+ if (rc != APR_SUCCESS) {
+ Perl_croak(aTHX_ "filedes retrieval failed!");
+ }
+
+ MP_TRACE_o(MP_FUNC, "converting fd %d", os_file);
+
+ /* let's try without the dup, it seems to work fine:
+
+ fd = PerlLIO_dup(os_file);
+ MP_TRACE_o(MP_FUNC, "fd old: %d, new %d", os_file, fd);
+ if (!(retval = PerlIO_fdopen(fd, mode))) {
+ ...
+ }
+
+ in any case if we later decide to dup, remember to:
+
+ apr_file_close(file);
+
+ after PerlIO_fdopen() or that fh will be leaked
+
+ */
+
+ if (!(retval = PerlIO_fdopen(os_file, mode))) {
+ PerlLIO_close(fd);
+ Perl_croak(aTHX_ "fdopen failed!");
+ }
+
+ return retval;
+}
+
+SV *modperl_apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file,
+ apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type)
+{
+ SV *retval = modperl_perl_gensym(aTHX_ "APR::PerlIO");
+ GV *gv = (GV*)SvRV(retval);
+
+ gv_IOadd(gv);
+
+ switch (type) {
+ case MODPERL_APR_PERLIO_HOOK_WRITE:
+ IoIFP(GvIOp(gv)) = IoOFP(GvIOp(gv)) =
+ modperl_apr_perlio_apr_file_to_PerlIO(aTHX_ file, type);
+ IoFLAGS(GvIOp(gv)) |= IOf_FLUSH;
+ IoTYPE(GvIOp(gv)) = IoTYPE_WRONLY;
+ break;
+ case MODPERL_APR_PERLIO_HOOK_READ:
+ IoIFP(GvIOp(gv)) = modperl_apr_perlio_apr_file_to_PerlIO(aTHX_ file,
+ type);
+ IoTYPE(GvIOp(gv)) = IoTYPE_RDONLY;
+ break;
+ };
+
+ return sv_2mortal(retval);
+}
+
+void modperl_apr_perlio_init(pTHX)
+{
+ APR_REGISTER_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_glob);
+}
+
+#endif /* PERLIO_LAYERS */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.h b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.h
new file mode 100644
index 0000000..15c853a
--- /dev/null
+++ b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.h
@@ -0,0 +1,83 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_APR_PERLIO_H
+#define MODPERL_APR_PERLIO_H
+
+#ifdef PERLIO_LAYERS
+#include "perliol.h"
+#else
+#include "iperlsys.h"
+#endif
+
+#include "apr_portable.h"
+#include "apr_file_io.h"
+#include "apr_errno.h"
+
+#ifndef MP_SOURCE_SCAN
+#include "apr_optional.h"
+#endif
+
+/* 5.6.0 */
+#ifndef IoTYPE_RDONLY
+#define IoTYPE_RDONLY '<'
+#endif
+#ifndef IoTYPE_WRONLY
+#define IoTYPE_WRONLY '>'
+#endif
+
+typedef enum {
+ MODPERL_APR_PERLIO_HOOK_READ,
+ MODPERL_APR_PERLIO_HOOK_WRITE
+} modperl_apr_perlio_hook_e;
+
+#ifndef MP_SOURCE_SCAN
+void modperl_apr_perlio_init(pTHX);
+#endif
+
+/* The following functions can be used from other .so libs, they just
+ * need to load APR::PerlIO perl module first
+ */
+#ifndef MP_SOURCE_SCAN
+
+#ifdef PERLIO_LAYERS
+PerlIO *modperl_apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file,
+ apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type);
+APR_DECLARE_OPTIONAL_FN(PerlIO *,
+ modperl_apr_perlio_apr_file_to_PerlIO,
+ (pTHX_ apr_file_t *file, apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type));
+#endif /* PERLIO_LAYERS */
+
+
+SV *modperl_apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file,
+ apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type);
+APR_DECLARE_OPTIONAL_FN(SV *,
+ modperl_apr_perlio_apr_file_to_glob,
+ (pTHX_ apr_file_t *file, apr_pool_t *pool,
+ modperl_apr_perlio_hook_e type));
+#endif /* MP_SOURCE_SCAN */
+
+#endif /* MODPERL_APR_PERLIO_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Pool/APR__Pool.h b/2_0_13/xs/APR/Pool/APR__Pool.h
new file mode 100644
index 0000000..4a168b3
--- /dev/null
+++ b/2_0_13/xs/APR/Pool/APR__Pool.h
@@ -0,0 +1,398 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define MP_APR_POOL_NEW "APR::Pool::new"
+
+typedef struct {
+ SV *sv;
+#ifdef USE_ITHREADS
+ PerlInterpreter *perl;
+ modperl_interp_t *interp;
+#endif
+} mpxs_pool_account_t;
+
+/* XXX: this implementation has a problem with perl ithreads. if a
+ * custom pool is allocated, and then a thread is spawned we now have
+ * two copies of the pool object, each living in a different perl
+ * interpreter, both pointing to the same memory address of the apr
+ * pool.
+ *
+ * need to write a CLONE class method could properly clone the
+ * thread's copied object, but it's tricky:
+ * - it needs to call parent_get() on the copied object and allocate a
+ * new pool from that parent's pool
+ * - it needs to reinstall any registered cleanup callbacks (can we do
+ * that?) may be we can skip those?
+ */
+
+#ifndef MP_SOURCE_SCAN
+#ifdef USE_ITHREADS
+#include "apr_optional.h"
+APR_OPTIONAL_FN_TYPE(modperl_interp_unselect) *modperl_opt_interp_unselect;
+APR_OPTIONAL_FN_TYPE(modperl_thx_interp_get) *modperl_opt_thx_interp_get;
+#endif
+#endif
+
+#define MP_APR_POOL_SV_HAS_OWNERSHIP(sv) mpxs_pool_is_custom(sv)
+
+/* before the magic is freed, one needs to carefully detach the
+ * dependant pool magic added by mpxs_add_pool_magic (most of the time
+ * it'd be a parent pool), and postpone its destruction, until after
+ * the child pool is destroyed. Since if we don't do that the
+ * destruction of the parent pool will destroy the child pool C guts
+ * and when perl unware of that the rug was pulled under the feet will
+ * continue destructing the child pool, things will crash
+ */
+#define MP_APR_POOL_SV_DROPS_OWNERSHIP_RUN(acct) STMT_START { \
+ MAGIC *mg = mg_find(acct->sv, PERL_MAGIC_ext); \
+ if (mg && mg->mg_obj) { \
+ sv_2mortal(mg->mg_obj); \
+ mg->mg_obj = (SV *)NULL; \
+ mg->mg_flags &= ~MGf_REFCOUNTED; \
+ } \
+ mg_free(acct->sv); \
+ SvIVX(acct->sv) = 0; \
+} STMT_END
+
+#ifdef USE_ITHREADS
+
+#define MP_APR_POOL_SV_DROPS_OWNERSHIP(acct) STMT_START { \
+ dTHXa(acct->perl); \
+ MP_APR_POOL_SV_DROPS_OWNERSHIP_RUN(acct); \
+ if (modperl_opt_interp_unselect && acct->interp) { \
+ /* this will decrement the interp refcnt until \
+ * there are no more references, in which case \
+ * the interpreter will be putback into the mip \
+ */ \
+ MP_TRACE_i(MP_FUNC, "DO: calling interp_unselect(0x%lx)", \
+ acct->interp); \
+ (void)modperl_opt_interp_unselect(acct->interp); \
+ } \
+} STMT_END
+
+#define MP_APR_POOL_SV_TAKES_OWNERSHIP(acct_sv, pool) STMT_START { \
+ mpxs_pool_account_t *acct = apr_palloc(pool, sizeof *acct); \
+ acct->sv = acct_sv; \
+ acct->perl = aTHX; \
+ SvIVX(acct_sv) = PTR2IV(pool); \
+ \
+ sv_magic(acct_sv, (SV *)NULL, PERL_MAGIC_ext, \
+ MP_APR_POOL_NEW, sizeof(MP_APR_POOL_NEW)); \
+ \
+ apr_pool_cleanup_register(pool, (void *)acct, \
+ mpxs_apr_pool_cleanup, \
+ apr_pool_cleanup_null); \
+ \
+ /* make sure interpreter is not putback into the mip \
+ * until this cleanup has run. \
+ */ \
+ if (modperl_opt_thx_interp_get) { \
+ if ((acct->interp = modperl_opt_thx_interp_get(aTHX))) { \
+ acct->interp->refcnt++; \
+ MP_TRACE_i(MP_FUNC, "TO: (0x%lx)->refcnt incremented to %ld", \
+ acct->interp, acct->interp->refcnt); \
+ } \
+ } \
+} STMT_END
+
+#else /* !USE_ITHREADS */
+
+#define MP_APR_POOL_SV_DROPS_OWNERSHIP MP_APR_POOL_SV_DROPS_OWNERSHIP_RUN
+
+#define MP_APR_POOL_SV_TAKES_OWNERSHIP(acct_sv, pool) STMT_START { \
+ mpxs_pool_account_t *acct = apr_palloc(pool, sizeof *acct); \
+ acct->sv = acct_sv; \
+ SvIVX(acct_sv) = PTR2IV(pool); \
+ \
+ sv_magic(acct_sv, (SV *)NULL, PERL_MAGIC_ext, \
+ MP_APR_POOL_NEW, sizeof(MP_APR_POOL_NEW)); \
+ \
+ apr_pool_cleanup_register(pool, (void *)acct, \
+ mpxs_apr_pool_cleanup, \
+ apr_pool_cleanup_null); \
+} STMT_END
+
+#endif /* USE_ITHREADS */
+
+
+/* XXX: should we make it a new global tracing category
+ * MOD_PERL_TRACE=p for tracing pool management? */
+#define MP_POOL_TRACE_DO 0
+
+#if MP_POOL_TRACE_DO && defined(MP_TRACE)
+#define MP_POOL_TRACE modperl_trace
+#else
+#define MP_POOL_TRACE if (0) modperl_trace
+#endif
+
+/* invalidate all Perl objects referencing the data sv stored in the
+ * pool and the sv itself. this is needed when a parent pool triggers
+ * apr_pool_destroy on its child pools
+ */
+static MP_INLINE apr_status_t
+mpxs_apr_pool_cleanup(void *cleanup_data)
+{
+ mpxs_pool_account_t *acct = cleanup_data;
+ MP_APR_POOL_SV_DROPS_OWNERSHIP(acct);
+ return APR_SUCCESS;
+}
+
+/**
+ * Create a new pool or subpool.
+ * @param parent_pool_obj an APR::Pool object or an "APR::Pool" class
+ * @return a new pool or subpool
+ */
+static MP_INLINE SV *mpxs_apr_pool_create(pTHX_ SV *parent_pool_obj)
+{
+ apr_pool_t *parent_pool = mpxs_sv_object_deref(parent_pool_obj, apr_pool_t);
+ apr_pool_t *child_pool = NULL;
+
+ MP_POOL_TRACE(MP_FUNC, "parent pool 0x%l", (unsigned long)parent_pool);
+ (void)apr_pool_create(&child_pool, parent_pool);
+
+#if APR_POOL_DEBUG
+ /* useful for pools debugging, can grep for APR::Pool::new */
+ apr_pool_tag(child_pool, MP_APR_POOL_NEW);
+#endif
+
+ /* allocation corruption validation: I saw this happening when the
+ * same pool was destroyed more than once, should be fixed now,
+ * but still the check is not redundant */
+ if (child_pool == parent_pool) {
+ Perl_croak(aTHX_ "a newly allocated sub-pool 0x%lx "
+ "is the same as its parent 0x%lx, aborting",
+ (unsigned long)child_pool, (unsigned long)parent_pool);
+ }
+
+#if APR_POOL_DEBUG
+ /* child <-> parent <-> ... <-> top ancestry traversal */
+ {
+ apr_pool_t *p = child_pool;
+ apr_pool_t *pp;
+
+ while ((pp = apr_pool_parent_get(p))) {
+ MP_POOL_TRACE(MP_FUNC, "parent 0x%lx, child 0x%lx",
+ (unsigned long)pp, (unsigned long)p);
+
+ if (apr_pool_is_ancestor(pp, p)) {
+ MP_POOL_TRACE(MP_FUNC, "0x%lx is a subpool of 0x%lx",
+ (unsigned long)p, (unsigned long)pp);
+ }
+ p = pp;
+ }
+ }
+#endif
+
+ {
+ SV *rv = sv_setref_pv(newSV(0), "APR::Pool", (void*)child_pool);
+ SV *sv = SvRV(rv);
+
+ /* Each newly created pool must be destroyed only once. Calling
+ * apr_pool_destroy will destroy the pool and its children pools,
+ * however a perl object for a sub-pool will still keep a pointer
+ * to the pool which was already destroyed. When this object is
+ * DESTROYed, apr_pool_destroy will be called again. In the best
+ * case it'll try to destroy a non-existing pool, but in the worst
+ * case it'll destroy a different valid pool which has been given
+ * the same memory allocation wrecking havoc. Therefore we must
+ * ensure that when sub-pools are destroyed via the parent pool,
+ * their cleanup callbacks will destroy the guts of their perl
+ * objects, so when those perl objects, pointing to memory
+ * previously allocated by destroyed sub-pools or re-used already
+ * by new pools, will get their time to DESTROY, they won't make a
+ * mess, trying to destroy an already destroyed pool or even worse
+ * a pool allocate in the place of the old one.
+ */
+
+ MP_APR_POOL_SV_TAKES_OWNERSHIP(sv, child_pool);
+
+ MP_POOL_TRACE(MP_FUNC, "sub-pool p: 0x%lx, sv: 0x%lx, rv: 0x%lx",
+ (unsigned long)child_pool, sv, rv);
+
+ if (parent_pool) {
+ mpxs_add_pool_magic(rv, parent_pool_obj);
+ }
+
+ return rv;
+ }
+}
+
+static MP_INLINE void mpxs_APR__Pool_clear(pTHX_ SV *obj)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(obj);
+ SV *sv = SvRV(obj);
+
+ if (!MP_APR_POOL_SV_HAS_OWNERSHIP(sv)) {
+ MP_POOL_TRACE(MP_FUNC, "parent pool (0x%lx) is a core pool",
+ (unsigned long)p);
+ apr_pool_clear(p);
+ return;
+ }
+
+ MP_POOL_TRACE(MP_FUNC,
+ "parent pool (0x%lx) is a custom pool, sv 0x%lx",
+ (unsigned long)p,
+ (unsigned long)sv);
+
+ apr_pool_clear(p);
+
+ /* apr_pool_clear runs & removes the cleanup, so we need to restore
+ * it. Since clear triggers mpxs_apr_pool_cleanup call, our
+ * object's guts get nuked too, so we need to restore them too */
+
+ MP_APR_POOL_SV_TAKES_OWNERSHIP(sv, p);
+}
+
+
+typedef struct {
+ SV *cv;
+ SV *arg;
+ apr_pool_t *p;
+#ifdef USE_ITHREADS
+ PerlInterpreter *perl;
+ modperl_interp_t *interp;
+#endif
+} mpxs_cleanup_t;
+
+/**
+ * callback wrapper for Perl cleanup subroutines
+ * @param data internal storage
+ */
+
+
+static apr_status_t mpxs_cleanup_run(void *data)
+{
+ int count;
+ mpxs_cleanup_t *cdata = (mpxs_cleanup_t *)data;
+#ifdef USE_ITHREADS
+ dTHXa(cdata->perl);
+#endif
+ dSP;
+
+ ENTER;SAVETMPS;
+ PUSHMARK(SP);
+ if (cdata->arg) {
+ XPUSHs(cdata->arg);
+ }
+ PUTBACK;
+
+ save_gp(PL_errgv, 1); /* local *@ */
+ count = call_sv(cdata->cv, G_SCALAR|G_EVAL);
+
+ SPAGAIN;
+
+ if (count == 1) {
+ (void)POPs; /* the return value is ignored */
+ }
+
+ if (SvTRUE(ERRSV)) {
+ Perl_warn(aTHX_ "APR::Pool: cleanup died: %s",
+ SvPV_nolen(ERRSV));
+ }
+
+ PUTBACK;
+ FREETMPS;LEAVE;
+
+ SvREFCNT_dec(cdata->cv);
+ if (cdata->arg) {
+ SvREFCNT_dec(cdata->arg);
+ }
+
+#ifdef USE_ITHREADS
+ if (cdata->interp && modperl_opt_interp_unselect) {
+ /* this will decrement the interp refcnt until
+ * there are no more references, in which case
+ * the interpreter will be putback into the mip
+ */
+ MP_TRACE_i(MP_FUNC, "calling interp_unselect(0x%lx)", cdata->interp);
+ (void)modperl_opt_interp_unselect(cdata->interp);
+ }
+#endif
+
+ /* the return value is ignored by apr_pool_destroy anyway */
+ return APR_SUCCESS;
+}
+
+/**
+ * register cleanups to run
+ * @param p pool with which to associate the cleanup
+ * @param cv subroutine reference to run
+ * @param arg optional argument to pass to the subroutine
+ */
+static MP_INLINE void mpxs_apr_pool_cleanup_register(pTHX_ apr_pool_t *p,
+ SV *cv, SV *arg)
+{
+ mpxs_cleanup_t *data =
+ (mpxs_cleanup_t *)apr_pcalloc(p, sizeof(*data));
+
+ data->cv = SvREFCNT_inc(cv);
+ data->arg = arg ? SvREFCNT_inc(arg) : (SV *)NULL;
+ data->p = p;
+#ifdef USE_ITHREADS
+ data->perl = aTHX;
+ /* make sure interpreter is not putback into the mip
+ * until this cleanup has run.
+ */
+ if (modperl_opt_thx_interp_get) {
+ if ((data->interp = modperl_opt_thx_interp_get(data->perl))) {
+ data->interp->refcnt++;
+ MP_TRACE_i(MP_FUNC, "(0x%lx)->refcnt incremented to %ld",
+ data->interp, data->interp->refcnt);
+ }
+ }
+#endif
+
+ apr_pool_cleanup_register(p, data,
+ mpxs_cleanup_run,
+ apr_pool_cleanup_null);
+}
+
+
+static MP_INLINE SV *
+mpxs_apr_pool_parent_get(pTHX_ apr_pool_t *child_pool)
+{
+ apr_pool_t *parent_pool = apr_pool_parent_get(child_pool);
+
+ if (parent_pool) {
+ return SvREFCNT_inc(mp_xs_APR__Pool_2obj(parent_pool));
+ }
+ else {
+ MP_POOL_TRACE(MP_FUNC, "pool (0x%lx) has no parents",
+ (unsigned long)child_pool);
+ return &PL_sv_undef;
+ }
+}
+
+/**
+ * destroy a pool
+ * @param obj an APR::Pool object
+ */
+static MP_INLINE void mpxs_apr_pool_DESTROY(pTHX_ SV *obj)
+{
+ SV *sv = SvRV(obj);
+
+ if (MP_APR_POOL_SV_HAS_OWNERSHIP(sv)) {
+ apr_pool_t *p = mpxs_sv_object_deref(obj, apr_pool_t);
+ apr_pool_destroy(p);
+ }
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/SockAddr/APR__SockAddr.h b/2_0_13/xs/APR/SockAddr/APR__SockAddr.h
new file mode 100644
index 0000000..06790d9
--- /dev/null
+++ b/2_0_13/xs/APR/SockAddr/APR__SockAddr.h
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE char *
+mpxs_apr_sockaddr_ip_get(pTHX_ apr_sockaddr_t *sockaddr)
+{
+ char *addr = NULL;
+
+ (void)apr_sockaddr_ip_get(&addr, sockaddr);
+
+ return addr;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Socket/APR__Socket.h b/2_0_13/xs/APR/Socket/APR__Socket.h
new file mode 100644
index 0000000..0c2a88e
--- /dev/null
+++ b/2_0_13/xs/APR/Socket/APR__Socket.h
@@ -0,0 +1,134 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+apr_size_t mpxs_APR__Socket_recv(pTHX_ apr_socket_t *socket,
+ SV *buffer,
+ apr_size_t len)
+{
+ apr_status_t rc;
+
+ mpxs_sv_grow(buffer, len);
+ rc = apr_socket_recv(socket, SvPVX(buffer), &len);
+
+ if (!(rc == APR_SUCCESS || rc == APR_EOF)) {
+ modperl_croak(aTHX_ rc, "APR::Socket::recv");
+ }
+
+ mpxs_sv_cur_set(buffer, len);
+ SvTAINTED_on(buffer);
+ return len;
+}
+
+static MP_INLINE
+apr_size_t mpxs_apr_socket_send(pTHX_ apr_socket_t *socket,
+ SV *sv_buf, SV *sv_len)
+{
+ apr_size_t buf_len;
+ char *buffer = SvPV(sv_buf, buf_len);
+
+ if (sv_len) {
+ if (buf_len < SvIV(sv_len)) {
+ Perl_croak(aTHX_ "the 3rd arg (%d) is bigger than the "
+ "length (%d) of the 2nd argument",
+ (int)SvIV(sv_len), buf_len);
+ }
+ buf_len = SvIV(sv_len);
+ }
+
+ MP_RUN_CROAK(apr_socket_send(socket, buffer, &buf_len),
+ "APR::Socket::send");
+
+ return buf_len;
+}
+
+static MP_INLINE
+apr_interval_time_t mpxs_apr_socket_timeout_get(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ apr_interval_time_t t;
+ APR__Socket APR__Socket;
+
+ /* this also magically assings to APR_Socket ;-) */
+ mpxs_usage_va_1(APR__Socket, "$socket->timeout_get()");
+
+ MP_RUN_CROAK(apr_socket_timeout_get(APR__Socket, &t),
+ "APR::Socket::timeout_get");
+ return t;
+}
+
+static MP_INLINE
+void mpxs_APR__Socket_timeout_set(pTHX_ apr_socket_t *socket,
+ apr_interval_time_t t)
+{
+ MP_RUN_CROAK(apr_socket_timeout_set(socket, t),
+ "APR::Socket::timeout_set");
+}
+
+
+
+static MP_INLINE
+apr_int32_t mpxs_APR__Socket_opt_get(pTHX_ apr_socket_t *socket,
+ apr_int32_t opt)
+{
+ apr_int32_t val;
+ MP_RUN_CROAK(apr_socket_opt_get(socket, opt, &val),
+ "APR::Socket::opt_get");
+ return val;
+}
+
+static MP_INLINE
+void mpxs_APR__Socket_opt_set(pTHX_ apr_socket_t *socket, apr_int32_t opt,
+ apr_int32_t val)
+{
+ MP_RUN_CROAK(apr_socket_opt_set(socket, opt, val),
+ "APR::Socket::opt_set");
+}
+
+static MP_INLINE
+apr_status_t mpxs_APR__Socket_poll(apr_socket_t *socket,
+ apr_pool_t *pool,
+ apr_interval_time_t timeout,
+ apr_int16_t reqevents)
+{
+ apr_pollfd_t fd;
+ apr_int32_t nsds;
+
+ /* what to poll */
+ fd.p = pool;
+ fd.desc_type = APR_POLL_SOCKET;
+ fd.desc.s = socket;
+ fd.reqevents = reqevents;
+ fd.rtnevents = 0; /* XXX: not really necessary to set this */
+
+ return apr_poll(&fd, 1, &nsds, timeout);
+}
+
+#ifndef WIN32
+static MP_INLINE int mpxs_APR__Socket_fileno(pTHX_ apr_socket_t *socket)
+{
+ apr_os_sock_t s;
+ apr_os_sock_get(&s, socket);
+ return s;
+}
+#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Status/APR__Status.h b/2_0_13/xs/APR/Status/APR__Status.h
new file mode 100644
index 0000000..b741cb2
--- /dev/null
+++ b/2_0_13/xs/APR/Status/APR__Status.h
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_errno.h"
+
+#define mpxs_APR__Status_is_EAGAIN APR_STATUS_IS_EAGAIN
+#define mpxs_APR__Status_is_EACCES APR_STATUS_IS_EACCES
+#define mpxs_APR__Status_is_ENOENT APR_STATUS_IS_ENOENT
+#define mpxs_APR__Status_is_EOF APR_STATUS_IS_EOF
+#define mpxs_APR__Status_is_ECONNABORTED APR_STATUS_IS_ECONNABORTED
+#define mpxs_APR__Status_is_ECONNRESET APR_STATUS_IS_ECONNRESET
+#define mpxs_APR__Status_is_TIMEUP APR_STATUS_IS_TIMEUP
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/String/APR__String.h b/2_0_13/xs/APR/String/APR__String.h
new file mode 100644
index 0000000..a257cdd
--- /dev/null
+++ b/2_0_13/xs/APR/String/APR__String.h
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+SV *mpxs_APR__String_strfsize(pTHX_ apr_off_t size)
+{
+ char buff[5];
+
+ apr_strfsize(size, buff);
+
+ return newSVpvn(buff, 4);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Table/APR__Table.h b/2_0_13/xs/APR/Table/APR__Table.h
new file mode 100644
index 0000000..4ef6c49
--- /dev/null
+++ b/2_0_13/xs/APR/Table/APR__Table.h
@@ -0,0 +1,241 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mpxs_APR__Table_STORE apr_table_set
+#define mpxs_APR__Table_DELETE apr_table_unset
+#define mpxs_APR__Table_CLEAR apr_table_clear
+
+#define MPXS_DO_TABLE_N_MAGIC_RETURN(call) \
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); \
+ apr_table_t *t = call; \
+ SV *t_sv = modperl_hash_tie(aTHX_ "APR::Table", (SV *)NULL, t); \
+ mpxs_add_pool_magic(t_sv, p_sv); \
+ return t_sv;
+
+static MP_INLINE SV *mpxs_APR__Table_make(pTHX_ SV *p_sv, int nelts)
+{
+ MPXS_DO_TABLE_N_MAGIC_RETURN(apr_table_make(p, nelts));
+}
+
+
+static MP_INLINE SV *mpxs_APR__Table_copy(pTHX_ apr_table_t *base, SV *p_sv)
+{
+ MPXS_DO_TABLE_N_MAGIC_RETURN(apr_table_copy(p, base));
+}
+
+static MP_INLINE SV *mpxs_APR__Table_overlay(pTHX_ apr_table_t *base,
+ apr_table_t *overlay, SV *p_sv)
+{
+ MPXS_DO_TABLE_N_MAGIC_RETURN(apr_table_overlay(p, overlay, base));
+}
+
+
+typedef struct {
+ SV *cv;
+ apr_hash_t *filter;
+ PerlInterpreter *perl;
+} mpxs_table_do_cb_data_t;
+
+typedef int (*mpxs_apr_table_do_cb_t)(void *, const char *, const char *);
+
+static int mpxs_apr_table_do_cb(void *data,
+ const char *key, const char *val)
+{
+ mpxs_table_do_cb_data_t *tdata = (mpxs_table_do_cb_data_t *)data;
+ dTHXa(tdata->perl);
+ dSP;
+ int rv = 0;
+
+ /* Skip completely if something is wrong */
+ if (!(tdata && tdata->cv && key && val)) {
+ return 0;
+ }
+
+ /* Skip entries if not in our filter list */
+ if (tdata->filter) {
+ if (!apr_hash_get(tdata->filter, key, APR_HASH_KEY_STRING)) {
+ return 1;
+ }
+ }
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSVpv(key,0)));
+ XPUSHs(sv_2mortal(newSVpv(val,0)));
+ PUTBACK;
+
+ rv = call_sv(tdata->cv, 0);
+ SPAGAIN;
+ rv = (1 == rv) ? POPi : 1;
+ PUTBACK;
+
+ FREETMPS;
+ LEAVE;
+
+ /* rv of 0 aborts the traversal */
+ return rv;
+}
+
+static MP_INLINE
+int mpxs_apr_table_do(pTHX_ I32 items, SV **MARK, SV **SP)
+{
+ apr_table_t *table;
+ SV *sub;
+ mpxs_table_do_cb_data_t tdata;
+
+ mpxs_usage_va_2(table, sub, "$table->do(sub, [@filter])");
+
+ tdata.cv = sub;
+ tdata.filter = NULL;
+#ifdef USE_ITHREADS
+ tdata.perl = aTHX;
+#endif
+
+ if (items > 2) {
+ char *filter_entry;
+ STRLEN len;
+
+ tdata.filter = apr_hash_make(apr_table_elts(table)->pool);
+
+ while (MARK <= SP) {
+ filter_entry = SvPV(*MARK, len);
+ apr_hash_set(tdata.filter, filter_entry, len, "1");
+ MARK++;
+ }
+ }
+
+ /* XXX: would be nice to be able to call apr_table_vdo directly,
+ * but I don't think it's possible to create/populate something
+ * that smells like a va_list with our list of filters specs
+ */
+
+ apr_table_do(mpxs_apr_table_do_cb, (void *)&tdata, table, NULL);
+
+ /* Free tdata.filter or wait for the pool to go away? */
+
+ /* XXX: return return value of apr_table_do once we require newer httpd */
+ return 1;
+}
+
+static MP_INLINE int mpxs_APR__Table_EXISTS(apr_table_t *t, const char *key)
+{
+ return (NULL == apr_table_get(t, key)) ? 0 : 1;
+}
+
+/* Note: SvCUR is used as the iterator state counter, why not ;-? */
+#define mpxs_apr_table_iterix(sv) \
+SvCUR(SvRV(sv))
+
+#define mpxs_apr_table_nextkey(t, sv) \
+ ((apr_table_entry_t *) \
+ apr_table_elts(t)->elts)[mpxs_apr_table_iterix(sv)++].key
+
+static MP_INLINE const char *mpxs_APR__Table_NEXTKEY(pTHX_ SV *tsv, SV *key)
+{
+ apr_table_t *t;
+ SV *rv = modperl_hash_tied_object_rv(aTHX_ "APR::Table", tsv);
+ if (!SvROK(rv)) {
+ Perl_croak(aTHX_ "Usage: $table->NEXTKEY($key): "
+ "first argument not an APR::Table object");
+ }
+
+ t = INT2PTR(apr_table_t *, SvIVX(SvRV(rv)));
+
+ if (apr_is_empty_table(t)) {
+ return NULL;
+ }
+
+ if (key == NULL) {
+ mpxs_apr_table_iterix(rv) = 0; /* reset iterator index */
+ }
+
+ if (mpxs_apr_table_iterix(rv) < apr_table_elts(t)->nelts) {
+ return mpxs_apr_table_nextkey(t, rv);
+ }
+
+ mpxs_apr_table_iterix(rv) = 0;
+
+ return NULL;
+}
+
+/* Try to shortcut apr_table_get by fetching the key using the current
+ * iterator (unless it's inactive or points at different key).
+ */
+static MP_INLINE const char *mpxs_APR__Table_FETCH(pTHX_ SV *tsv,
+ const char *key)
+{
+ SV* rv = modperl_hash_tied_object_rv(aTHX_ "APR::Table", tsv);
+ const int i = mpxs_apr_table_iterix(rv);
+ apr_table_t *t = INT2PTR(apr_table_t *, SvIVX(SvRV(rv)));
+ const apr_array_header_t *arr = apr_table_elts(t);
+ apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts;
+
+ if (i > 0 && i <= arr->nelts && !strcasecmp(key, elts[i-1].key)) {
+ return elts[i-1].val;
+ }
+ else {
+ return apr_table_get(t, key);
+ }
+}
+
+
+MP_STATIC XS(MPXS_apr_table_get)
+{
+ dXSARGS;
+
+ if (items != 2) {
+ Perl_croak(aTHX_ "Usage: $table->get($key)");
+ }
+
+ mpxs_PPCODE({
+ APR__Table t = modperl_hash_tied_object(aTHX_ "APR::Table", ST(0));
+ const char *key = (const char *)SvPV_nolen(ST(1));
+
+ if (!t) {
+ XSRETURN_UNDEF;
+ }
+
+ if (GIMME_V == G_SCALAR) {
+ const char *val = apr_table_get(t, key);
+
+ if (val) {
+ XPUSHs(sv_2mortal(newSVpv((char*)val, 0)));
+ }
+ }
+ else {
+ const apr_array_header_t *arr = apr_table_elts(t);
+ apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts;
+ int i;
+
+ for (i = 0; i < arr->nelts; i++) {
+ if (!elts[i].key || strcasecmp(elts[i].key, key)) {
+ continue;
+ }
+ XPUSHs(sv_2mortal(newSVpv(elts[i].val,0)));
+ }
+ }
+ });
+
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/ThreadMutex/APR__ThreadMutex.h b/2_0_13/xs/APR/ThreadMutex/APR__ThreadMutex.h
new file mode 100644
index 0000000..3f4a395
--- /dev/null
+++ b/2_0_13/xs/APR/ThreadMutex/APR__ThreadMutex.h
@@ -0,0 +1,37 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define apr_thread_mutex_DESTROY apr_thread_mutex_destroy
+
+static MP_INLINE
+SV *mpxs_apr_thread_mutex_create(pTHX_ SV *classname, SV *p_sv,
+ unsigned int flags)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_thread_mutex_t *mutex = NULL;
+ SV *mutex_sv;
+ (void)apr_thread_mutex_create(&mutex, flags, p);
+ mutex_sv = sv_setref_pv(newSV(0), "APR::ThreadMutex", (void*)mutex);
+ mpxs_add_pool_magic(mutex_sv, p_sv);
+ return mutex_sv;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/ThreadRWLock/APR__ThreadRWLock.h b/2_0_13/xs/APR/ThreadRWLock/APR__ThreadRWLock.h
new file mode 100644
index 0000000..a2d4d4b
--- /dev/null
+++ b/2_0_13/xs/APR/ThreadRWLock/APR__ThreadRWLock.h
@@ -0,0 +1,36 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define apr_thread_rwlock_DESTROY apr_thread_rwlock_destroy
+
+static MP_INLINE
+SV *mpxs_apr_thread_rwlock_create(pTHX_ SV *classname, SV *p_sv)
+{
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ apr_thread_rwlock_t *rwlock = NULL;
+ SV *rwlock_sv;
+ (void)apr_thread_rwlock_create(&rwlock, p);
+ rwlock_sv = sv_setref_pv(newSV(0), "APR::ThreadRWLock", (void*)rwlock);
+ mpxs_add_pool_magic(rwlock_sv, p_sv);
+ return rwlock_sv;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/URI/APR__URI.h b/2_0_13/xs/APR/URI/APR__URI.h
new file mode 100644
index 0000000..59589aa
--- /dev/null
+++ b/2_0_13/xs/APR/URI/APR__URI.h
@@ -0,0 +1,102 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+char *mpxs_apr_uri_unparse(pTHX_
+ apr_uri_t *uptr,
+ unsigned flags)
+{
+
+ /* apr =< 0.9.2-dev segfaults if hostname is set, but scheme is not.
+ * apr >= 0.9.2 simply uses "", which will force the user to set scheme
+ * since apr_uri_unparse is protocol-agnostic, it doesn't use
+ * 'http' as the default fallback anymore. so we use the same solution
+ */
+#if APR_MAJOR_VERSION == 0 && APR_MINOR_VERSION == 9 && \
+ (APR_PATCH_VERSION < 2 || APR_PATCH_VERSION == 2 && defined APR_IS_DEV_VERSION)
+ if (uptr->hostname && !uptr->scheme) {
+ uptr->scheme = "";
+ }
+#endif
+
+ return apr_uri_unparse(((modperl_uri_t *)uptr)->pool,
+ uptr, flags);
+}
+
+static MP_INLINE
+SV *mpxs_apr_uri_parse(pTHX_ SV *classname, SV *p_sv, const char *uri_string)
+{
+ SV *uri_sv;
+ apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
+ modperl_uri_t *uri = modperl_uri_new(p);
+
+ (void)apr_uri_parse(p, uri_string, &uri->uri);
+
+ uri_sv = sv_setref_pv(newSV(0), "APR::URI", (void*)uri);
+ mpxs_add_pool_magic(uri_sv, p_sv);
+
+ return uri_sv;
+}
+
+static MP_INLINE
+char *mpxs_APR__URI_port(pTHX_ apr_uri_t *uri, SV *portsv)
+{
+ char *port_str = uri->port_str;
+
+ if (portsv) {
+ if (SvOK(portsv)) {
+ STRLEN len;
+ char *port = SvPV(portsv, len);
+ uri->port_str = apr_pstrndup(((modperl_uri_t *)uri)->pool,
+ port, len);
+ uri->port = (int)SvIV(portsv);
+ }
+ else {
+ uri->port_str = NULL;
+ uri->port = 0;
+ }
+ }
+
+ return port_str;
+}
+
+static MP_INLINE
+SV *mpxs_APR__URI_rpath(pTHX_ apr_uri_t *apr_uri)
+{
+ modperl_uri_t *uri = (modperl_uri_t *)apr_uri;
+
+ if (uri->path_info) {
+ int uri_len = strlen(uri->uri.path);
+ int n = strlen(uri->path_info);
+ int set = uri_len - n;
+ if (set > 0) {
+ return newSVpv(uri->uri.path, set);
+ }
+ }
+ else {
+ if (uri->uri.path) {
+ return newSVpv(uri->uri.path, 0);
+ }
+ }
+ return (SV *)NULL;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/UUID/APR__UUID.h b/2_0_13/xs/APR/UUID/APR__UUID.h
new file mode 100644
index 0000000..db29a69
--- /dev/null
+++ b/2_0_13/xs/APR/UUID/APR__UUID.h
@@ -0,0 +1,58 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mpxs_apr_uuid_alloc() \
+(apr_uuid_t *)safemalloc(sizeof(apr_uuid_t))
+
+static MP_INLINE apr_uuid_t *mpxs_apr_uuid_get(pTHX_ SV *CLASS)
+{
+ apr_uuid_t *uuid = mpxs_apr_uuid_alloc();
+ apr_uuid_get(uuid);
+ return uuid;
+}
+
+static MP_INLINE void mp_apr_uuid_format(pTHX_ SV *sv, SV *obj)
+{
+ apr_uuid_t *uuid = mp_xs_sv2_uuid(obj);
+ mpxs_sv_grow(sv, APR_UUID_FORMATTED_LENGTH);
+ apr_uuid_format(SvPVX(sv), uuid);
+ mpxs_sv_cur_set(sv, APR_UUID_FORMATTED_LENGTH);
+}
+
+static MP_INLINE apr_uuid_t *mpxs_apr_uuid_parse(pTHX_ SV *CLASS, char *buf)
+{
+ apr_uuid_t *uuid = mpxs_apr_uuid_alloc();
+ apr_uuid_parse(uuid, buf);
+ return uuid;
+}
+
+MP_STATIC XS(MPXS_apr_uuid_format)
+{
+ dXSARGS;
+
+ mpxs_usage_items_1("uuid");
+
+ mpxs_set_targ(mp_apr_uuid_format, ST(0));
+}
+
+#define apr_uuid_DESTROY(uuid) safefree(uuid)
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/Util/APR__Util.h b/2_0_13/xs/APR/Util/APR__Util.h
new file mode 100644
index 0000000..e51aa7e
--- /dev/null
+++ b/2_0_13/xs/APR/Util/APR__Util.h
@@ -0,0 +1,28 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE int mpxs_apr_password_validate(pTHX_ const char *passwd,
+ const char *hash)
+{
+ return apr_password_validate(passwd, hash) == APR_SUCCESS;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/APR/aprext/Makefile.PL b/2_0_13/xs/APR/aprext/Makefile.PL
new file mode 100644
index 0000000..ccf1731
--- /dev/null
+++ b/2_0_13/xs/APR/aprext/Makefile.PL
@@ -0,0 +1,60 @@
+use strict;
+use warnings;
+
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+require ModPerl::Code;
+use Apache2::Build ();
+
+my $build = ModPerl::BuildMM::build_config();
+
+my $srcdir = '../../../src/modules/perl';
+my @names = ModPerl::Code::src_apr_ext();
+
+my(@obj, @clean, %src);
+for (@names) {
+ push @obj, join '.', $_, 'o';
+ my $cfile = join '.', $_, 'c';
+ push @clean, $cfile;
+ $src{$cfile} = "$srcdir/$cfile";
+}
+
+push @obj, q{modperl_dummy.o};
+
+my @skip = qw(dynamic test);
+push @skip, q{static}
+ unless (Apache2::Build::BUILD_APREXT);
+
+my %args = (NAME => 'lib' . $build->{MP_APR_LIB},
+ VERSION_FROM => '../APR/APR.pm',
+ SKIP => [ @skip ] ,
+ LINKTYPE => 'static',
+ OBJECT => "@obj",
+ clean => { FILES => "@clean" },
+ );
+
+my $ccopts = $build->ccopts;
+
+# avoid referencing &perl_module outside of mod_perl
+$ccopts .= ' -DMP_IN_XS';
+
+$args{CCFLAGS} = $ccopts;
+
+ModPerl::BuildMM::WriteMakefile(%args);
+
+# avoid redefined warnings from imported postamble symbol from
+# elsewhere in other Makefile.PL files
+no warnings 'redefine';
+sub MY::postamble {
+ my $self = shift;
+ my $string = $self->ModPerl::BuildMM::MY::postamble;
+
+ $string .= join '', map {
+ "$_: $src{$_}\n\t\$(CP) $src{$_} .\n";
+ } sort keys %src;
+
+ # BSD make needs an empty target, even if the target is specified in .PHONY
+ $string .= "\ndynamic ::\n";
+
+ return $string;
+}
diff --git a/2_0_13/xs/APR/aprext/modperl_dummy.c b/2_0_13/xs/APR/aprext/modperl_dummy.c
new file mode 100644
index 0000000..8e936cb
--- /dev/null
+++ b/2_0_13/xs/APR/aprext/modperl_dummy.c
@@ -0,0 +1,36 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+
+/* FIXME: These functions are called from modperl_trace() in libaprext.lib
+ * but are normally defined in mod_perl.c which can't be included.
+ */
+
+int modperl_is_running(void)
+{
+ return 0;
+}
+
+int modperl_threads_started(void)
+{
+ return 0;
+}
+
+int modperl_threaded_mpm(void)
+{
+ return 0;
+}
diff --git a/2_0_13/xs/Apache2/Access/Apache2__Access.h b/2_0_13/xs/Apache2/Access/Apache2__Access.h
new file mode 100644
index 0000000..fe0759e
--- /dev/null
+++ b/2_0_13/xs/Apache2/Access/Apache2__Access.h
@@ -0,0 +1,175 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE SV *mpxs_ap_requires(pTHX_ request_rec *r)
+{
+ AV *av;
+ HV *hv;
+ register int x;
+ const apr_array_header_t *reqs_arr =
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || AP_SERVER_MINORVERSION_NUMBER>=3
+ 0;
+#else
+ ap_requires(r);
+#endif
+ require_line *reqs;
+
+ if (!reqs_arr) {
+ return &PL_sv_undef;
+ }
+
+ reqs = (require_line *)reqs_arr->elts;
+ av = newAV();
+
+ for (x=0; x < reqs_arr->nelts; x++) {
+ /* XXX should we do this or let PerlAuthzHandler? */
+ if (! (reqs[x].method_mask & (1 << r->method_number))) {
+ continue;
+ }
+
+ hv = newHV();
+
+ (void)hv_store(hv, "method_mask", 11,
+ newSViv((IV)reqs[x].method_mask), 0);
+
+ (void)hv_store(hv, "requirement", 11,
+ newSVpv(reqs[x].requirement,0), 0);
+
+ av_push(av, newRV_noinc((SV*)hv));
+ }
+
+ return newRV_noinc((SV*)av);
+}
+
+static MP_INLINE
+void mpxs_ap_allow_methods(pTHX_ I32 items, SV **MARK, SV **SP)
+{
+ request_rec *r;
+ SV *reset;
+
+ mpxs_usage_va_2(r, reset, "$r->allow_methods(reset, ...)");
+
+ if (SvIV(reset)) {
+ ap_clear_method_list(r->allowed_methods);
+ }
+
+ while (MARK <= SP) {
+ STRLEN n_a;
+ char *method = SvPV(*MARK, n_a);
+ ap_method_list_add(r->allowed_methods, method);
+ MARK++;
+ }
+}
+
+static MP_INLINE void mpxs_insert_auth_cfg(pTHX_ request_rec *r,
+ char *directive,
+ char *val)
+{
+ const char *errmsg;
+ AV *config = newAV();
+
+ av_push(config, Perl_newSVpvf(aTHX_ "%s %s", directive, val));
+
+ errmsg =
+ modperl_config_insert_request(aTHX_ r,
+ newRV_noinc((SV*)config),
+ OR_AUTHCFG, NULL,
+ MP_HTTPD_OVERRIDE_OPTS_UNSET);
+
+ if (errmsg) {
+ Perl_warn(aTHX_ "Can't change %s to '%s'\n", directive, val);
+ }
+
+ SvREFCNT_dec((SV*)config);
+}
+
+static MP_INLINE
+const char *mpxs_Apache2__RequestRec_auth_type(pTHX_ request_rec *r,
+ char *type)
+{
+ const char *ret = NULL;
+
+ if (type) {
+ mpxs_insert_auth_cfg(aTHX_ r, "AuthType", type);
+ }
+
+ ret = ap_auth_type(r);
+ if (!ret) {
+ return "none";
+ }
+
+ return ret;
+}
+
+static MP_INLINE
+const char *mpxs_Apache2__RequestRec_auth_name(pTHX_ request_rec *r,
+ char *name)
+{
+ if (name) {
+ mpxs_insert_auth_cfg(aTHX_ r, "AuthName", name);
+ }
+
+ return ap_auth_name(r);
+}
+
+MP_STATIC XS(MPXS_ap_get_basic_auth_pw)
+{
+ dXSARGS;
+ request_rec *r;
+ const char *sent_pw = NULL;
+ int rc;
+
+ mpxs_usage_items_1("r");
+
+ mpxs_PPCODE({
+ r = mp_xs_sv2_r(ST(0));
+
+ /* Default auth-type to Basic */
+ if (!ap_auth_type(r)) {
+ mpxs_Apache2__RequestRec_auth_type(aTHX_ r, "Basic");
+ }
+
+ rc = ap_get_basic_auth_pw(r, &sent_pw);
+
+ EXTEND(SP, 2);
+ PUSHs_mortal_iv(rc);
+ if (rc == OK) {
+ PUSHs_mortal_pv(sent_pw);
+ }
+ else {
+ PUSHs(&PL_sv_undef);
+ }
+ });
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_allow_override_opts(pTHX_ request_rec *r)
+{
+#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS
+ core_dir_config *cfg = ap_get_module_config(r->per_dir_config,
+ &core_module);
+ return cfg->override_opts;
+#else
+ return MP_HTTPD_OVERRIDE_OPTS_DEFAULT;
+#endif
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/CmdParms/Apache2__CmdParms.h b/2_0_13/xs/Apache2/CmdParms/Apache2__CmdParms.h
new file mode 100644
index 0000000..66497f2
--- /dev/null
+++ b/2_0_13/xs/Apache2/CmdParms/Apache2__CmdParms.h
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "modperl_module.h"
+
+static MP_INLINE
+SV *mpxs_Apache2__CmdParms_info(pTHX_ cmd_parms *parms)
+{
+ const char *data = ((modperl_module_cmd_data_t *)parms->info)->cmd_data;
+
+ if (data) {
+ return newSVpv(data, 0);
+ }
+
+ return &PL_sv_undef;
+}
+
+static MP_INLINE
+void mpxs_Apache2__CmdParms_add_config(pTHX_ cmd_parms *parms, SV *lines)
+{
+ const char *errmsg = modperl_config_insert_parms(aTHX_ parms, lines);
+ if (errmsg) {
+ Perl_croak(aTHX_ "$parms->add_config() has failed: %s", errmsg);
+ }
+}
+
+static MP_INLINE
+int mpxs_Apache2__CmdParms_override_opts(pTHX_ cmd_parms *parms)
+{
+#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS
+ return parms->override_opts;
+#else
+ return MP_HTTPD_OVERRIDE_OPTS_DEFAULT;
+#endif
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Command/Apache2__Command.h b/2_0_13/xs/Apache2/Command/Apache2__Command.h
new file mode 100644
index 0000000..9527d77
--- /dev/null
+++ b/2_0_13/xs/Apache2/Command/Apache2__Command.h
@@ -0,0 +1,25 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mpxs_Apache2__Command_next(cmd) \
+(++cmd, ((cmd && cmd->name) ? cmd : NULL))
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Connection/Apache2__Connection.h b/2_0_13/xs/Apache2/Connection/Apache2__Connection.h
new file mode 100644
index 0000000..9cdb2cd
--- /dev/null
+++ b/2_0_13/xs/Apache2/Connection/Apache2__Connection.h
@@ -0,0 +1,49 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* backwards compat for c->keepalive (see ap_mmn.h) */
+#if MODULE_MAGIC_NUMBER < 20020625
+typedef int ap_conn_keepalive_e;
+#endif
+
+static MP_INLINE
+apr_socket_t *mpxs_Apache2__Connection_client_socket(pTHX_ conn_rec *c,
+ apr_socket_t *s)
+{
+ apr_socket_t *socket =
+ ap_get_module_config(c->conn_config, &core_module);
+
+ if (s) {
+ ap_set_module_config(c->conn_config, &core_module, s);
+ }
+
+ return socket;
+}
+
+static MP_INLINE
+const char *mpxs_Apache2__Connection_get_remote_host(pTHX_ conn_rec *c,
+ int type,
+ ap_conf_vector_t *dir_config)
+{
+ return ap_get_remote_host(c, (void *)dir_config, type, NULL);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h b/2_0_13/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h
new file mode 100644
index 0000000..40e0c5f
--- /dev/null
+++ b/2_0_13/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h
@@ -0,0 +1,50 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+SV *mpxs_Apache2__Connection_pnotes(pTHX_ conn_rec *c, SV *key, SV *val)
+{
+ MP_dCCFG;
+
+ modperl_config_con_init(c, ccfg);
+
+ if (!ccfg) {
+ return &PL_sv_undef;
+ }
+
+ return modperl_pnotes(aTHX_ &ccfg->pnotes, key, val, c->pool);
+}
+
+static MP_INLINE
+void mpxs_Apache2__Connection_pnotes_kill(pTHX_ conn_rec *c)
+{
+ MP_dCCFG;
+
+ modperl_config_con_init(c, ccfg);
+
+ if (!ccfg) {
+ return;
+ }
+
+ modperl_pnotes_kill(&ccfg->pnotes);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Const/Const.pm b/2_0_13/xs/Apache2/Const/Const.pm
new file mode 100644
index 0000000..05b84c3
--- /dev/null
+++ b/2_0_13/xs/Apache2/Const/Const.pm
@@ -0,0 +1,27 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache2::Const;
+
+use ModPerl::Const ();
+use XSLoader ();
+
+our $VERSION = do { require mod_perl2; $mod_perl2::VERSION };
+our @ISA = qw(ModPerl::Const);
+
+XSLoader::load(__PACKAGE__, $VERSION);
+
+1;
diff --git a/2_0_13/xs/Apache2/Const/Const.xs b/2_0_13/xs/Apache2/Const/Const.xs
new file mode 100644
index 0000000..5bfc153
--- /dev/null
+++ b/2_0_13/xs/Apache2/Const/Const.xs
@@ -0,0 +1,25 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+#include "modperl_const.h"
+
+MODULE = Apache2::Const PACKAGE = Apache2::Const
+
+PROTOTYPES: disable
+
+BOOT:
+ MP_newModPerlConstXS("Apache2");
diff --git a/2_0_13/xs/Apache2/Const/Makefile.PL b/2_0_13/xs/Apache2/Const/Makefile.PL
new file mode 100644
index 0000000..895bd8e
--- /dev/null
+++ b/2_0_13/xs/Apache2/Const/Makefile.PL
@@ -0,0 +1,7 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => 'Apache2::Const',
+ VERSION_FROM => 'Const.pm',
+);
diff --git a/2_0_13/xs/Apache2/Directive/Apache2__Directive.h b/2_0_13/xs/Apache2/Directive/Apache2__Directive.h
new file mode 100644
index 0000000..2350e31
--- /dev/null
+++ b/2_0_13/xs/Apache2/Directive/Apache2__Directive.h
@@ -0,0 +1,204 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mpxs_Apache2__Directive_conftree() ap_conftree
+
+/* XXX: this is only useful for <Perl> at the moment */
+static MP_INLINE SV *mpxs_Apache2__Directive_as_string(pTHX_
+ ap_directive_t *self)
+{
+ ap_directive_t *d;
+ SV *sv = newSVpv("", 0);
+
+ for (d = self->first_child; d; d = d->next) {
+ sv_catpv(sv, d->directive);
+ sv_catpv(sv, " ");
+ sv_catpv(sv, d->args);
+ sv_catpv(sv, "\n");
+ }
+
+ return sv;
+}
+
+
+/* Adds an entry to a hash, vivifying hash/array for multiple entries */
+static void hash_insert(pTHX_ HV *hash, const char *key,
+ int keylen, const char *args,
+ int argslen, SV *value)
+{
+ HV *subhash;
+ AV *args_array;
+ SV **hash_ent = hv_fetch(hash, key, keylen, 0);
+
+ if (value) {
+ if (!hash_ent) {
+ subhash = newHV();
+ (void)hv_store(hash, key, keylen, newRV_noinc((SV *)subhash), 0);
+ }
+ else {
+ subhash = (HV *)SvRV(*hash_ent);
+ }
+
+ (void)hv_store(subhash, args, argslen, value, 0);
+ }
+ else {
+ if (hash_ent) {
+ if (SvROK(*hash_ent) && (SVt_PVAV == SvTYPE(SvRV(*hash_ent)))) {
+ args_array = (AV *)SvRV(*hash_ent);
+ }
+ else {
+ args_array = newAV();
+ av_push(args_array, newSVsv(*hash_ent));
+ (void)hv_store(hash, key, keylen,
+ newRV_noinc((SV *)args_array), 0);
+ }
+ av_push(args_array, newSVpv(args, argslen));
+ }
+ else {
+ (void)hv_store(hash, key, keylen, newSVpv(args, argslen), 0);
+ }
+ }
+}
+
+static MP_INLINE SV *mpxs_Apache2__Directive_as_hash(pTHX_
+ ap_directive_t *tree)
+{
+ const char *directive;
+ int directive_len;
+ const char *args;
+ int args_len;
+
+ HV *hash = newHV();
+ SV *subtree;
+
+ while (tree) {
+ directive = tree->directive;
+ directive_len = strlen(directive);
+ args = tree->args;
+ args_len = strlen(args);
+
+ if (tree->first_child) {
+
+ /* Skip the prefix '<' */
+ if ('<' == directive[0]) {
+ directive++;
+ directive_len--;
+ }
+
+ /* Skip the postfix '>' */
+ if ('>' == args[args_len-1]) {
+ args_len--;
+ }
+
+ subtree = mpxs_Apache2__Directive_as_hash(aTHX_ tree->first_child);
+ hash_insert(aTHX_ hash, directive, directive_len,
+ args, args_len, subtree);
+ }
+ else {
+ hash_insert(aTHX_ hash, directive, directive_len,
+ args, args_len, (SV *)NULL);
+ }
+
+ tree = tree->next;
+ }
+
+ return newRV_noinc((SV *)hash);
+}
+
+MP_STATIC XS(MPXS_Apache2__Directive_lookup)
+{
+ dXSARGS;
+
+ if (items < 2 || items > 3) {
+ Perl_croak(aTHX_
+ "Usage: Apache2::Directive::lookup(self, key, [args])");
+ }
+
+ mpxs_PPCODE({
+ Apache2__Directive tree;
+ char *value;
+ const char *directive;
+ const char *args;
+ int args_len;
+ int directive_len;
+
+ char *key = (char *)SvPV_nolen(ST(1));
+ int scalar_context = (G_SCALAR == GIMME_V);
+
+ if (SvROK(ST(0)) && sv_derived_from(ST(0), "Apache2::Directive")) {
+ IV tmp = SvIV((SV*)SvRV(ST(0)));
+ tree = INT2PTR(Apache2__Directive,tmp);
+ }
+ else {
+ tree = ap_conftree;
+ }
+
+ if (items < 3) {
+ value = NULL;
+ }
+ else {
+ value = (char *)SvPV_nolen(ST(2));
+ }
+
+ while (tree) {
+ directive = tree->directive;
+ directive_len = strlen(directive);
+
+ /* Remove starting '<' for container directives */
+ if (directive[0] == '<') {
+ directive++;
+ directive_len--;
+ }
+
+ if (0 == strncasecmp(directive, key, directive_len)) {
+
+ if (value) {
+ args = tree->args;
+ args_len = strlen(args);
+
+ /* Skip the postfix '>' */
+ if ('>' == args[args_len-1]) {
+ args_len--;
+ }
+
+ }
+
+ if ( (!value) || (0 == strncasecmp(args, value, args_len)) ) {
+ if (tree->first_child) {
+ XPUSHs(sv_2mortal(mpxs_Apache2__Directive_as_hash(
+ aTHX_ tree->first_child)));
+ }
+ else {
+ XPUSHs(sv_2mortal(newSVpv(tree->args, 0)));
+ }
+
+ if (scalar_context) {
+ break;
+ }
+ }
+ }
+
+ tree = tree->next ? tree->next : NULL;
+ }
+ });
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Filter/Apache2__Filter.h b/2_0_13/xs/Apache2/Filter/Apache2__Filter.h
new file mode 100644
index 0000000..bc55137
--- /dev/null
+++ b/2_0_13/xs/Apache2/Filter/Apache2__Filter.h
@@ -0,0 +1,376 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mp_xs_sv2_modperl_filter(sv) \
+ ((SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) \
+ || (Perl_croak(aTHX_ "argument is not a blessed reference"),0) ? \
+ modperl_filter_mg_get(aTHX_ sv) : NULL)
+
+#define mpxs_Apache2__Filter_TIEHANDLE(stashsv, sv) \
+ modperl_newSVsv_obj(aTHX_ stashsv, sv)
+
+#define mpxs_Apache2__Filter_PRINT mpxs_Apache2__Filter_print
+
+static MP_INLINE apr_size_t mpxs_Apache2__Filter_print(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ modperl_filter_t *modperl_filter;
+ apr_size_t bytes = 0;
+
+ mpxs_usage_va_1(modperl_filter, "$filter->print(...)");
+
+ MP_TRACE_f(MP_FUNC, "from %s",
+ ((modperl_filter_ctx_t *)modperl_filter->f->ctx)->handler->name);
+ if (modperl_filter->mode == MP_OUTPUT_FILTER_MODE) {
+ mpxs_write_loop(modperl_output_filter_write,
+ modperl_filter, "Apache2::Filter::print");
+ }
+ else {
+ mpxs_write_loop(modperl_input_filter_write,
+ modperl_filter, "Apache2::Filter::print");
+ }
+
+ /* XXX: ap_rflush if $| */
+
+ return bytes;
+}
+
+static MP_INLINE apr_size_t mpxs_Apache2__Filter_read(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ modperl_filter_t *modperl_filter;
+ apr_size_t wanted, len=0;
+ SV *buffer;
+
+ mpxs_usage_va_2(modperl_filter, buffer, "$filter->read(buf, [len])");
+
+ MP_TRACE_f(MP_FUNC, "from %s",
+ ((modperl_filter_ctx_t *)modperl_filter->f->ctx)->handler->name);
+
+ if (items > 2) {
+ wanted = SvIV(*MARK);
+ }
+ else {
+ wanted = MP_IOBUFSIZE;
+ }
+
+ if (modperl_filter->mode == MP_INPUT_FILTER_MODE) {
+ /* XXX: if we ever will have a need to change the read
+ * discipline: (input_mode, block, readbytes) from the filter
+ * we can provide an accessor method to modify the values
+ * supplied by the filter chain */
+ len = modperl_input_filter_read(aTHX_ modperl_filter, buffer, wanted);
+ }
+ else {
+ len = modperl_output_filter_read(aTHX_ modperl_filter, buffer, wanted);
+ }
+
+ /* must run any set magic */
+ SvSETMAGIC(buffer);
+
+ SvTAINTED_on(buffer);
+
+ return len;
+}
+
+static MP_INLINE U16 *modperl_filter_attributes(pTHX_ SV *package, SV *cvrv)
+{
+ return modperl_code_attrs(aTHX_ (CV*)SvRV(cvrv));
+}
+
+#ifdef MP_TRACE
+#define trace_attr() \
+ MP_TRACE_f(MP_FUNC, "applied %s attribute to %s handler", attribute, \
+ HvNAME(stash))
+#else
+#define trace_attr()
+#endif
+
+/* we can't eval at this stage, since the package is not compiled yet,
+ * we are still parsing the source.
+ */
+#define MODPERL_FILTER_ATTACH_ATTR_CODE(cv, string, len) \
+ { \
+ char *str; \
+ len -= 2; /* s/ \( | \) //x */ \
+ string++; /* skip the opening '(' */ \
+ Newx(str, len+1, char); \
+ Copy(string, str, len+1, char); \
+ str[len] = '\0'; /* remove the closing ')' */ \
+ sv_magic(cv, (SV *)NULL, '~', NULL, -1); \
+ SvMAGIC(cv)->mg_ptr = str; \
+ }
+
+
+MP_STATIC XS(MPXS_modperl_filter_attributes)
+{
+ dXSARGS;
+ U16 *attrs = modperl_filter_attributes(aTHX_ ST(0), ST(1));
+ I32 i;
+#ifdef MP_TRACE
+ HV *stash = gv_stashsv(ST(0), TRUE);
+#endif
+
+ for (i=2; i < items; i++) {
+ STRLEN len;
+ char *pv = SvPV(ST(i), len);
+ char *attribute = pv;
+
+ if (strnEQ(pv, "Filter", 6)) {
+ pv += 6;
+ }
+
+ switch (*pv) {
+ case 'C':
+ if (strEQ(pv, "ConnectionHandler")) {
+ *attrs |= MP_FILTER_CONNECTION_HANDLER;
+ trace_attr();
+ continue;
+ }
+ case 'I':
+ if (strEQ(pv, "InitHandler")) {
+ *attrs |= MP_FILTER_INIT_HANDLER;
+ trace_attr();
+ continue;
+ }
+ case 'H':
+ if (strnEQ(pv, "HasInitHandler", 14)) {
+ STRLEN code_len;
+ pv += 14; /* skip over the attr name */
+ code_len = len - (pv - attribute);
+ MODPERL_FILTER_ATTACH_ATTR_CODE(SvRV(ST(1)), pv, code_len);
+ *attrs |= MP_FILTER_HAS_INIT_HANDLER;
+ trace_attr();
+ continue;
+ }
+ case 'R':
+ if (strEQ(pv, "RequestHandler")) {
+ *attrs |= MP_FILTER_REQUEST_HANDLER;
+ trace_attr();
+ continue;
+ }
+ default:
+ /* XXX: there could be more than one attr to pass through */
+ XPUSHs_mortal_pv(attribute);
+ XSRETURN(1);
+ }
+ }
+
+ XSRETURN_EMPTY;
+}
+
+static MP_INLINE SV *mpxs_Apache2__Filter_ctx(pTHX_
+ ap_filter_t *filter,
+ SV *data)
+{
+ modperl_filter_ctx_t *ctx = (modperl_filter_ctx_t *)(filter->ctx);
+
+ /* XXX: is it possible that the same filter, during a single
+ * request or connection cycle, will be invoked by different perl
+ * interpreters? if that happens we are in trouble, if we need to
+ * return an SV living in a different interpreter. may be there is
+ * a way to use one of the perl internal functions to clone an SV
+ * (and it can contain any references)
+ */
+
+ if (data != (SV *)NULL) {
+ if (ctx->data) {
+ if (SvOK(ctx->data) && SvREFCNT(ctx->data)) {
+ /* release the previously stored SV so we don't leak
+ * an SV */
+ SvREFCNT_dec(ctx->data);
+ }
+ }
+
+#ifdef USE_ITHREADS
+ if (!ctx->interp) {
+ ctx->interp = modperl_thx_interp_get(aTHX);
+ MP_INTERP_REFCNT_inc(ctx->interp);
+ }
+#endif
+ ctx->data = SvREFCNT_inc(data);
+ }
+
+ return ctx->data ? SvREFCNT_inc(ctx->data) : &PL_sv_undef;
+}
+
+static MP_INLINE SV *mpxs_Apache2__Filter_seen_eos(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ modperl_filter_t *modperl_filter;
+
+ if ((items < 1) || (items > 2) || !(mpxs_sv2_obj(modperl_filter, *MARK))) {
+ Perl_croak(aTHX_ "usage: $filter->seen_eos([$set])");
+ }
+ MARK++;
+
+ if (items == 2) {
+ modperl_filter->seen_eos = SvTRUE(*MARK) ? 1 : 0;
+ }
+
+ return modperl_filter->seen_eos ? &PL_sv_yes : &PL_sv_no;
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_add_input_filter(pTHX_ request_rec *r,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ r,
+ r->connection,
+ MP_FILTER_REQUEST_INPUT_NAME,
+ MP_INPUT_FILTER_MODE,
+ ap_add_input_filter,
+ callback,
+ "InputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_add_output_filter(pTHX_ request_rec *r,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ r,
+ r->connection,
+ MP_FILTER_REQUEST_OUTPUT_NAME,
+ MP_OUTPUT_FILTER_MODE,
+ ap_add_output_filter,
+ callback,
+ "OutputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache2__Connection_add_input_filter(pTHX_ conn_rec *c,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ NULL,
+ c,
+ MP_FILTER_CONNECTION_INPUT_NAME,
+ MP_INPUT_FILTER_MODE,
+ ap_add_input_filter,
+ callback,
+ "InputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache2__Connection_add_output_filter(pTHX_ conn_rec *c,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ NULL,
+ c,
+ MP_FILTER_CONNECTION_OUTPUT_NAME,
+ MP_OUTPUT_FILTER_MODE,
+ ap_add_output_filter,
+ callback,
+ "OutputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache2__Filter_remove(pTHX_ I32 items, SV **MARK, SV **SP)
+{
+ modperl_filter_t *modperl_filter;
+ ap_filter_t *f;
+
+ if (items < 1) {
+ Perl_croak(aTHX_ "usage: $filter->remove()");
+ }
+
+ modperl_filter = mp_xs_sv2_modperl_filter(*MARK);
+
+ /* native filter */
+ if (!modperl_filter) {
+ f = INT2PTR(ap_filter_t *, SvIV(SvRV(*MARK)));
+ MP_TRACE_f(MP_FUNC,
+ " %s\n\n\t non-modperl filter removes itself",
+ f->frec->name);
+
+ /* the filter can reside in only one chain. hence we try to
+ * remove it from both, the input and output chains, since
+ * unfortunately we can't tell what kind of filter is that and
+ * whether the first call was successful
+ */
+ ap_remove_input_filter(f);
+ ap_remove_output_filter(f);
+ return;
+ }
+
+ f = modperl_filter->f;
+
+ MP_TRACE_f(MP_FUNC, " %s\n\n\tfilter removes itself",
+ ((modperl_filter_ctx_t *)f->ctx)->handler->name);
+
+ if (modperl_filter->mode == MP_INPUT_FILTER_MODE) {
+ ap_remove_input_filter(f);
+ }
+ else {
+ ap_remove_output_filter(f);
+ }
+}
+
+static MP_INLINE
+apr_status_t mpxs_Apache2__Filter_fflush(pTHX_ ap_filter_t *filter,
+ apr_bucket_brigade *brigade)
+{
+ apr_status_t rc = ap_fflush(filter, brigade);
+ /* if users don't bother to check the success, do it on their
+ * behalf */
+ if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
+ modperl_croak(aTHX_ rc, "Apache2::Filter::fflush");
+ }
+
+ return rc;
+}
+
+static MP_INLINE
+apr_status_t mpxs_Apache2__Filter_get_brigade(pTHX_
+ ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ ap_input_mode_t mode,
+ apr_read_type_e block,
+ apr_off_t readbytes)
+{
+ apr_status_t rc = ap_get_brigade(f, bb, mode, block, readbytes);
+ /* if users don't bother to check the success, do it on their
+ * behalf */
+ if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
+ modperl_croak(aTHX_ rc, "Apache2::Filter::get_brigade");
+ }
+
+ return rc;
+}
+
+static MP_INLINE
+apr_status_t mpxs_Apache2__Filter_pass_brigade(pTHX_ ap_filter_t *f,
+ apr_bucket_brigade *bb)
+{
+ apr_status_t rc = ap_pass_brigade(f, bb);
+ /* if users don't bother to check the success, do it on their
+ * behalf */
+ if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
+ modperl_croak(aTHX_ rc, "Apache2::Filter::pass_brigade");
+ }
+
+ return rc;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Log/Apache2__Log.h b/2_0_13/xs/Apache2/Log/Apache2__Log.h
new file mode 100644
index 0000000..e3c558b
--- /dev/null
+++ b/2_0_13/xs/Apache2/Log/Apache2__Log.h
@@ -0,0 +1,347 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static void mpxs_Apache2__Log_BOOT(pTHX)
+{
+ av_push(get_av("Apache2::Log::Request::ISA", TRUE),
+ newSVpv("Apache2::Log", 12));
+ av_push(get_av("Apache2::Log::Server::ISA", TRUE),
+ newSVpv("Apache2::Log", 12));
+}
+
+#define croak_inval_obj() \
+ Perl_croak(aTHX_ "Argument is not an Apache2::RequestRec " \
+ "or Apache2::ServerRec object")
+
+static void mpxs_ap_log_error(pTHX_ int level, SV *sv, SV *msg)
+{
+ char *file = NULL;
+ int line = 0;
+ char *str;
+ SV *svstr = (SV *)NULL;
+ STRLEN n_a;
+ int lmask = level & APLOG_LEVELMASK;
+ server_rec *s;
+ request_rec *r = NULL;
+
+ if (SvROK(sv) && sv_isa(sv, "Apache2::Log::Request")) {
+ r = INT2PTR(request_rec *, SvObjIV(sv));
+ s = r->server;
+ }
+ else if (SvROK(sv) && sv_isa(sv, "Apache2::Log::Server")) {
+ s = INT2PTR(server_rec *, SvObjIV(sv));
+ }
+ else {
+ s = modperl_global_get_server_rec();
+ }
+
+ if ((lmask >= APLOG_DEBUG) && (mp_loglevel(s) >= APLOG_DEBUG)) {
+ COP *cop = PL_curcop;
+ file = CopFILE(cop); /* (caller)[1] */
+ line = CopLINE(cop); /* (caller)[2] */
+ }
+
+ if ((mp_loglevel(s) >= lmask) &&
+ SvROK(msg) && (SvTYPE(SvRV(msg)) == SVt_PVCV)) {
+ dSP;
+ ENTER;SAVETMPS;
+ PUSHMARK(sp);
+ (void)call_sv(msg, G_SCALAR);
+ SPAGAIN;
+ svstr = POPs;
+ (void)SvREFCNT_inc(svstr);
+ PUTBACK;
+ FREETMPS;LEAVE;
+ str = SvPV(svstr,n_a);
+ }
+ else {
+ str = SvPV(msg,n_a);
+ }
+
+ if (r) {
+ ap_log_rerror(file, line, mp_module_index_ level, 0, r,
+ "%s", str);
+ }
+ else {
+ ap_log_error(file, line, mp_module_index_ level, 0, s,
+ "%s", str);
+ }
+
+ if (svstr) {
+ SvREFCNT_dec(svstr);
+ }
+}
+
+#define MP_LOG_REQUEST 1
+#define MP_LOG_SERVER 2
+
+static SV *mpxs_Apache2__Log_log(pTHX_ SV *sv, int logtype)
+{
+ SV *svretval;
+ void *retval;
+ char *pclass;
+
+ switch (logtype) {
+ case MP_LOG_REQUEST:
+ pclass = "Apache2::Log::Request";
+ retval = (void *)modperl_sv2request_rec(aTHX_ sv);
+ break;
+ case MP_LOG_SERVER:
+ pclass = "Apache2::Log::Server";
+ retval = (void *)modperl_sv2server_rec(aTHX_ sv);
+ break;
+ default:
+ croak_inval_obj();
+ };
+
+ svretval = newSV(0);
+ sv_setref_pv(svretval, pclass, (void*)retval);
+
+ return svretval;
+}
+
+#define mpxs_Apache2__RequestRec_log(sv) \
+ mpxs_Apache2__Log_log(aTHX_ sv, MP_LOG_REQUEST)
+
+#define mpxs_Apache2__ServerRec_log(sv) \
+ mpxs_Apache2__Log_log(aTHX_ sv, MP_LOG_SERVER)
+
+static MP_INLINE SV *modperl_perl_do_join(pTHX_ SV **mark, SV **sp)
+{
+ SV *sv = newSV(0);
+ SV *delim;
+#ifdef WIN32
+ /* XXX: using PL_sv_no crashes on win32 with 5.6.1 */
+ delim = newSVpv("", 0);
+#else
+ delim = SvREFCNT_inc(&PL_sv_no);
+#endif
+
+ do_join(sv, delim, mark, sp);
+
+ SvREFCNT_dec(delim);
+
+ return sv;
+}
+
+#define my_do_join(m, s) \
+ modperl_perl_do_join(aTHX_ (m), (s))
+
+MP_STATIC XS(MPXS_Apache2__Log_dispatch)
+{
+ dXSARGS;
+ SV *msgsv;
+ int level;
+ char *name = GvNAME(CvGV(cv));
+
+ if (items < 2) {
+ Perl_croak(aTHX_ "usage: %s::%s(obj, ...)",
+ mpxs_cv_name());
+ }
+
+ if (items > 2) {
+ msgsv = my_do_join(MARK+1, SP);
+ }
+ else {
+ msgsv = ST(1);
+ (void)SvREFCNT_inc(msgsv);
+ }
+
+ switch (*name) {
+ case 'e':
+ if (*(name + 1) == 'r') {
+ level = APLOG_ERR;
+ break;
+ }
+ level = APLOG_EMERG;
+ break;
+ case 'w':
+ level = APLOG_WARNING;
+ break;
+ case 'n':
+ level = APLOG_NOTICE;
+ break;
+ case 'i':
+ level = APLOG_INFO;
+ break;
+ case 'd':
+ level = APLOG_DEBUG;
+ break;
+ case 'a':
+ level = APLOG_ALERT;
+ break;
+ case 'c':
+ level = APLOG_CRIT;
+ break;
+ default:
+ level = APLOG_ERR; /* should never get here */
+ break;
+ };
+
+ mpxs_ap_log_error(aTHX_ level, ST(0), msgsv);
+
+ SvREFCNT_dec(msgsv);
+
+ XSRETURN_EMPTY;
+}
+
+MP_STATIC XS(MPXS_Apache2__Log_LOG_MARK)
+{
+ dXSARGS;
+ ax = ax; /* -Wall */;
+
+ mpxs_PPCODE({
+ COP *cop = PL_curcop;
+
+ if (items) {
+ Perl_croak(aTHX_ "usage %s::%s()", mpxs_cv_name());
+ }
+
+ EXTEND(SP, 2);
+ PUSHs_mortal_pv(CopFILE(cop));
+ PUSHs_mortal_iv(CopLINE(cop));
+ });
+}
+
+MP_STATIC XS(MPXS_Apache2__Log_log_xerror)
+{
+ dXSARGS;
+ SV *msgsv = (SV *)NULL;
+ STRLEN n_a;
+ request_rec *r = NULL;
+ server_rec *s = NULL;
+ char *msgstr;
+ const char *file;
+ int line, level;
+ apr_status_t status;
+
+ if (items < 6) {
+ Perl_croak(aTHX_ "usage %s::%s(file, line, level, status, ...)",
+ mpxs_cv_name());
+ }
+
+ switch (*(GvNAME(CvGV(cv)) + 4)) { /* 4 == log_ */
+ case 'r':
+ r = modperl_xs_sv2request_rec(aTHX_ ST(0), NULL, cv);
+ break;
+ case 's':
+ s = modperl_sv2server_rec(aTHX_ ST(0));
+ break;
+ default:
+ croak_inval_obj();
+ };
+
+ file = (const char *)SvPV(ST(1), n_a);
+ line = (int)SvIV(ST(2));
+ level = (int)SvIV(ST(3));
+ status = (apr_status_t)SvIV(ST(4));
+
+ if (items > 6) {
+ msgsv = my_do_join(MARK+5, SP);
+ }
+ else {
+ msgsv = ST(5);
+ (void)SvREFCNT_inc(msgsv);
+ }
+
+ msgstr = SvPV(msgsv, n_a);
+
+ if (r) {
+ ap_log_rerror(file, line, mp_module_index_ level, status, r,
+ "%s", msgstr);
+ }
+ else {
+ ap_log_error(file, line, mp_module_index_ level, status, s,
+ "%s", msgstr);
+ }
+
+ SvREFCNT_dec(msgsv);
+
+ XSRETURN_EMPTY;
+}
+
+/*
+ * this function handles:
+ * $r->log_error
+ * $s->log_error
+ * $r->warn
+ * $s->warn
+ * Apache2::ServerRec::warn
+ */
+MP_STATIC XS(MPXS_Apache2__Log_log_error)
+{
+ dXSARGS;
+ request_rec *r = NULL;
+ server_rec *s = NULL;
+ int i = 0;
+ char *errstr = NULL;
+ SV *sv = (SV *)NULL;
+ STRLEN n_a;
+
+ if (items > 1) {
+ if (sv_isa(ST(0), "Apache2::ServerRec")) {
+ s = INT2PTR(server_rec *, SvObjIV(ST(0)));
+ }
+ else if ((r = modperl_xs_sv2request_rec(aTHX_ ST(0),
+ "Apache2::RequestRec", cv))) {
+ s = r->server;
+ }
+ }
+
+ if (s) {
+ i = 1;
+ }
+ else {
+ request_rec *r = NULL;
+ (void)modperl_tls_get_request_rec(&r);
+ if (r) {
+ s = r->server;
+ }
+ else {
+ s = modperl_global_get_server_rec();
+ }
+ }
+
+ if (items > 1+i) {
+ sv = my_do_join(MARK+i, SP); /* $sv = join '', @_[1..$#_] */
+ errstr = SvPV(sv,n_a);
+ }
+ else {
+ errstr = SvPV(ST(i),n_a);
+ }
+
+ switch (*GvNAME(CvGV(cv))) {
+ case 'w':
+ modperl_log_warn(s, errstr);
+ break;
+ default:
+ modperl_log_error(s, errstr);
+ break;
+ }
+
+ if (sv) {
+ SvREFCNT_dec(sv);
+ }
+
+ XSRETURN_EMPTY;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/MPM/Apache2__MPM.h b/2_0_13/xs/Apache2/MPM/Apache2__MPM.h
new file mode 100644
index 0000000..9ede5f3
--- /dev/null
+++ b/2_0_13/xs/Apache2/MPM/Apache2__MPM.h
@@ -0,0 +1,67 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE SV *mpxs_Apache2__MPM_query(pTHX_ SV *self, int query_code)
+{
+ int mpm_query_info;
+
+ apr_status_t retval = ap_mpm_query(query_code, &mpm_query_info);
+
+ if (retval == APR_SUCCESS) {
+ return newSViv(mpm_query_info);
+ }
+
+ return &PL_sv_undef;
+}
+
+static void mpxs_Apache2__MPM_BOOT(pTHX)
+{
+ /* implement Apache2::MPM->show and Apache2::MPM->is_threaded
+ * as constant subroutines, since this information will never
+ * change during an interpreter's lifetime */
+
+ int mpm_query_info;
+
+ apr_status_t retval = ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info);
+
+ if (retval == APR_SUCCESS) {
+ MP_TRACE_g(MP_FUNC, "defined Apache2::MPM->is_threaded() as %i",
+ mpm_query_info);
+
+ newCONSTSUB(PL_defstash, "Apache2::MPM::is_threaded",
+ newSViv(mpm_query_info));
+ }
+ else {
+ /* assign false (0) to sub if ap_mpm_query didn't succeed */
+ MP_TRACE_g(MP_FUNC, "defined Apache2::MPM->is_threaded() as 0");
+
+ newCONSTSUB(PL_defstash, "Apache2::MPM::is_threaded",
+ newSViv(0));
+ }
+
+ MP_TRACE_g(MP_FUNC, "defined Apache2::MPM->show() as %s",
+ ap_show_mpm());
+
+ newCONSTSUB(PL_defstash, "Apache2::MPM::show",
+ newSVpv(ap_show_mpm(), 0));
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Makefile.PL b/2_0_13/xs/Apache2/Makefile.PL
new file mode 100644
index 0000000..e662890
--- /dev/null
+++ b/2_0_13/xs/Apache2/Makefile.PL
@@ -0,0 +1,7 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => "Apache2_build",
+ VERSION => '0.01'
+);
diff --git a/2_0_13/xs/Apache2/Module/Apache2__Module.h b/2_0_13/xs/Apache2/Module/Apache2__Module.h
new file mode 100644
index 0000000..f95b6b6
--- /dev/null
+++ b/2_0_13/xs/Apache2/Module/Apache2__Module.h
@@ -0,0 +1,105 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define mpxs_Apache2__Module_top_module() ap_top_module
+
+static MP_INLINE int mpxs_Apache2__Module_loaded(pTHX_ char *name)
+{
+ char nameptr[256];
+ char *base;
+ module *modp;
+
+ /* Does the module name have a '.' in it ? */
+ if ((base = ap_strchr(name, '.'))) {
+ int len = base - name;
+
+ memcpy(nameptr, name, len);
+ memcpy(nameptr + len, ".c\0", 3);
+
+ /* check if module is loaded */
+ if (!(modp = ap_find_linked_module(nameptr))) {
+ return 0;
+ }
+
+ if (*(base + 1) == 'c') {
+ return 1;
+ }
+
+ /* if it ends in '.so', check if it was dynamically loaded */
+ if ((strlen(base+1) == 2) &&
+ (*(base + 1) == 's') && (*(base + 2) == 'o') &&
+ modp->dynamic_load_handle)
+ {
+ return 1;
+ }
+
+ return 0;
+ }
+ else {
+ return modperl_perl_module_loaded(aTHX_ name);
+ }
+}
+
+static MP_INLINE SV *mpxs_Apache2__Module_get_config(pTHX_
+ SV *pmodule,
+ server_rec *s,
+ ap_conf_vector_t *v)
+{
+ SV *obj = modperl_module_config_get_obj(aTHX_ pmodule, s, v);
+
+ return SvREFCNT_inc(obj);
+}
+
+static MP_INLINE
+int mpxs_Apache2__Module_ap_api_major_version(pTHX_ module *mod)
+{
+ return mod->version;
+}
+
+static MP_INLINE
+int mpxs_Apache2__Module_ap_api_minor_version(pTHX_ module *mod)
+{
+ return mod->minor_version;
+}
+
+static MP_INLINE void mpxs_Apache2__Module_add(pTHX_
+ char *package,
+ SV *cmds)
+{
+ const char *error;
+ server_rec *s;
+
+ if (!(SvROK(cmds) && (SvTYPE(SvRV(cmds)) == SVt_PVAV))) {
+ Perl_croak(aTHX_ "Usage: Apache2::Module::add(__PACKAGE__, [])");
+ }
+
+ s = modperl_global_get_server_rec();
+ error = modperl_module_add(s->process->pconf, s, package, cmds);
+
+ if (error) {
+ Perl_croak(aTHX_ "Apache2::Module::add(%s) failed : %s",
+ package, error);
+ }
+
+ return;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/RequestIO/Apache2__RequestIO.h b/2_0_13/xs/Apache2/RequestIO/Apache2__RequestIO.h
new file mode 100644
index 0000000..d477597
--- /dev/null
+++ b/2_0_13/xs/Apache2/RequestIO/Apache2__RequestIO.h
@@ -0,0 +1,401 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef WIN32
+/* win32 not happy with &PL_sv_no */
+# define SVNO newSViv(0)
+# define SVYES newSViv(1)
+#else
+# define SVNO &PL_sv_no
+# define SVYES &PL_sv_yes
+#endif
+
+#define mpxs_Apache2__RequestRec_TIEHANDLE(stashsv, sv) \
+modperl_newSVsv_obj(aTHX_ stashsv, sv)
+
+#define mpxs_Apache2__RequestRec_PRINT mpxs_Apache2__RequestRec_print
+#define mpxs_Apache2__RequestRec_PRINTF mpxs_ap_rprintf
+#define mpxs_Apache2__RequestRec_BINMODE(r) \
+ r ? SVYES : SVNO /* noop */
+#define mpxs_Apache2__RequestRec_CLOSE(r) \
+ r ? SVYES : SVNO /* noop */
+
+#define mpxs_Apache2__RequestRec_UNTIE(r, refcnt) \
+ (r && refcnt) ? SVYES : SVNO /* noop */
+
+#define mpxs_output_flush(r, rcfg, name) \
+ /* if ($|) */ \
+ if (IoFLUSH(PL_defoutgv)) { \
+ MP_TRACE_o(MP_FUNC, "(flush) %d bytes [%s]", \
+ rcfg->wbucket->outcnt, \
+ apr_pstrmemdup(rcfg->wbucket->pool, rcfg->wbucket->outbuf, \
+ rcfg->wbucket->outcnt)); \
+ MP_RUN_CROAK(modperl_wbucket_flush(rcfg->wbucket, TRUE), \
+ name); \
+ }
+
+static MP_INLINE apr_size_t mpxs_ap_rvputs(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ modperl_config_req_t *rcfg;
+ apr_size_t bytes = 0;
+ request_rec *r;
+ dMP_TIMES;
+
+ mpxs_usage_va_1(r, "$r->puts(...)");
+
+ rcfg = modperl_config_req_get(r);
+
+ MP_START_TIMES();
+
+ MP_CHECK_WBUCKET_INIT("$r->puts");
+ mpxs_write_loop(modperl_wbucket_write, rcfg->wbucket,
+ "Apache2::RequestIO::puts");
+
+ MP_END_TIMES();
+ MP_PRINT_TIMES("r->puts");
+
+ /* we do not check $| for this method,
+ * only in the functions called by the tied interface
+ */
+
+ return bytes;
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_print(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ modperl_config_req_t *rcfg;
+ request_rec *r;
+
+ /* bytes must be called bytes */
+ apr_size_t bytes = 0;
+
+ /* this also magically assings to r ;-) */
+ mpxs_usage_va_1(r, "$r->print(...)");
+
+ rcfg = modperl_config_req_get(r);
+
+ MP_CHECK_WBUCKET_INIT("$r->print");
+ mpxs_write_loop(modperl_wbucket_write, rcfg->wbucket,
+ "Apache2::RequestIO::print");
+
+ mpxs_output_flush(r, rcfg, "Apache2::RequestIO::print");
+
+ return bytes ? newSVuv(bytes) : newSVpvn("0E0", 3);
+}
+
+static MP_INLINE
+apr_size_t mpxs_ap_rprintf(pTHX_ I32 items, SV **MARK, SV **SP)
+{
+ modperl_config_req_t *rcfg;
+ request_rec *r;
+ apr_size_t bytes = 0;
+ SV *sv;
+
+ mpxs_usage_va(2, r, "$r->printf($fmt, ...)");
+
+ rcfg = modperl_config_req_get(r);
+
+ /* Reduce items by 1 since it otherwise includes the
+ * Apache2::RequestRec object, which shouldn't be included in the
+ * count of arguments being given to the sprintf() call.
+ */
+ --items;
+
+ /* XXX: we could have an rcfg->sprintf_buffer to reuse this SV
+ * across requests
+ */
+ sv = sv_newmortal();
+ modperl_perl_do_sprintf(aTHX_ sv, items, MARK);
+ bytes = SvCUR(sv);
+
+ MP_CHECK_WBUCKET_INIT("$r->printf");
+
+ MP_TRACE_o(MP_FUNC, "%d bytes [%s]", bytes, SvPVX(sv));
+
+ MP_RUN_CROAK(modperl_wbucket_write(aTHX_ rcfg->wbucket,
+ SvPVX(sv), &bytes),
+ "Apache2::RequestIO::printf");
+
+ mpxs_output_flush(r, rcfg, "Apache2::RequestIO::printf");
+
+ return bytes;
+}
+
+/* alias */
+#define mpxs_Apache2__RequestRec_WRITE(r, buffer, len, offset) \
+ mpxs_Apache2__RequestRec_write(aTHX_ r, buffer, len, offset)
+
+static MP_INLINE
+apr_size_t mpxs_Apache2__RequestRec_write(pTHX_ request_rec *r,
+ SV *buffer, apr_size_t len,
+ apr_off_t offset)
+{
+ apr_size_t wlen;
+ const char *buf;
+ STRLEN avail;
+ MP_dRCFG;
+
+ buf = (const char *)SvPV(buffer, avail);
+
+ if (len == -1) {
+ wlen = offset ? avail - offset : avail;
+ }
+ else {
+ wlen = len;
+ }
+
+ MP_CHECK_WBUCKET_INIT("$r->write");
+ MP_RUN_CROAK(modperl_wbucket_write(aTHX_ rcfg->wbucket,
+ buf+offset, &wlen),
+ "Apache2::RequestIO::write");
+
+ return wlen;
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_rflush(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ modperl_config_req_t *rcfg;
+ request_rec *r;
+
+ /* this also magically assings to r ;-) */
+ mpxs_usage_va_1(r, "$r->rflush()");
+
+ rcfg = modperl_config_req_get(r);
+
+ MP_CHECK_WBUCKET_INIT("$r->rflush");
+ MP_TRACE_o(MP_FUNC, "%d bytes [%s]",
+ rcfg->wbucket->outcnt,
+ apr_pstrmemdup(rcfg->wbucket->pool, rcfg->wbucket->outbuf,
+ rcfg->wbucket->outcnt));
+ MP_RUN_CROAK_RESET_OK(r->server,
+ modperl_wbucket_flush(rcfg->wbucket, TRUE),
+ "Apache2::RequestIO::rflush");
+}
+
+static MP_INLINE long mpxs_ap_get_client_block(pTHX_ request_rec *r,
+ SV *buffer, int bufsiz)
+{
+ long nrd = 0;
+
+ mpxs_sv_grow(buffer, bufsiz);
+
+ nrd = ap_get_client_block(r, SvPVX(buffer), bufsiz);
+
+ if (nrd > 0) {
+ mpxs_sv_cur_set(buffer, nrd);
+ SvTAINTED_on(buffer);
+ }
+ else {
+ sv_setpvn(buffer, "", 0);
+ }
+
+ /* must run any set magic */
+ SvSETMAGIC(buffer);
+
+ return nrd;
+}
+
+static MP_INLINE
+apr_status_t mpxs_setup_client_block(request_rec *r)
+{
+ if (!r->read_length) {
+ apr_status_t rc;
+
+ /* only do this once per-request */
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_perl: ap_setup_client_block failed: %d", rc);
+ return rc;
+ }
+ }
+
+ return APR_SUCCESS;
+}
+
+#define mpxs_should_client_block(r) \
+ (r->read_length || ap_should_client_block(r))
+
+#ifndef sv_setpvn_mg
+# define sv_setpvn_mg sv_setpvn
+#endif
+
+/* alias */
+#define mpxs_Apache2__RequestRec_READ(r, buffer, len, offset) \
+ mpxs_Apache2__RequestRec_read(aTHX_ r, buffer, len, offset)
+
+static SV *mpxs_Apache2__RequestRec_read(pTHX_ request_rec *r,
+ SV *buffer, apr_size_t len,
+ apr_off_t offset)
+{
+ SSize_t total;
+ STRLEN blen;
+
+ if (!SvOK(buffer)) {
+ sv_setpvn_mg(buffer, "", 0);
+ }
+
+ (void)SvPV_force(buffer, blen); /* make it a valid PV */
+
+ if (len <= 0) {
+ Perl_croak(aTHX_ "The LENGTH argument can't be negative");
+ }
+
+ /* handle negative offset */
+ if (offset < 0) {
+ if (-offset > (int)blen) Perl_croak(aTHX_ "Offset outside string");
+ offset += blen;
+ }
+
+ mpxs_sv_grow(buffer, len+offset);
+
+ /* need to pad with \0 if offset > size of the buffer */
+ if (offset > SvCUR(buffer)) {
+ Zero(SvEND(buffer), offset - SvCUR(buffer), char);
+ }
+
+ total = modperl_request_read(aTHX_ r, SvPVX(buffer)+offset, len);
+
+ /* modperl_request_read can return only >=0. So it's safe to do this. */
+ /* if total==0 we need to set the buffer length in case it is larger */
+ mpxs_sv_cur_set(buffer, offset+total);
+
+ /* must run any set magic */
+ SvSETMAGIC(buffer);
+
+ SvTAINTED_on(buffer);
+
+ return newSViv(total);
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_GETC(pTHX_ request_rec *r)
+{
+ char c[1] = "\0";
+
+ /* XXX: reimplement similar to read() w/o using the deprecated
+ * client_block interface */
+ if (mpxs_setup_client_block(r) == APR_SUCCESS) {
+ if (mpxs_should_client_block(r)) {
+ if (ap_get_client_block(r, c, 1) == 1) {
+ return newSVpvn((char *)&c, 1);
+ }
+ }
+ }
+
+ return &PL_sv_undef;
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_OPEN(pTHX_ SV *self, SV *arg1, SV *arg2)
+{
+ char *name;
+ STRLEN len;
+ SV *arg;
+ dHANDLE("STDOUT");
+
+ modperl_io_handle_untie(aTHX_ handle); /* untie *STDOUT */
+
+ if (arg2 && self) {
+ arg = newSVsv(arg1);
+ sv_catsv(arg, arg2);
+ }
+ else {
+ arg = arg1;
+ }
+
+ name = SvPV(arg, len);
+ return do_open(handle, name, len, FALSE, O_RDONLY, 0, (PerlIO *)NULL);
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_FILENO(pTHX_ request_rec *r)
+{
+ dHANDLE("STDOUT");
+ return PerlIO_fileno(IoOFP(TIEHANDLE_SV(handle)));
+}
+
+static MP_INLINE
+apr_status_t mpxs_Apache2__RequestRec_sendfile(pTHX_ request_rec *r,
+ const char *filename,
+ apr_off_t offset,
+ apr_size_t len)
+{
+ apr_size_t nbytes;
+ apr_status_t rc;
+ apr_file_t *fp;
+
+ rc = apr_file_open(&fp, filename, APR_READ|APR_BINARY,
+ APR_OS_DEFAULT, r->pool);
+
+ if (rc != APR_SUCCESS) {
+ if (GIMME_V == G_VOID) {
+ modperl_croak(aTHX_ rc,
+ apr_psprintf(r->pool,
+ "Apache2::RequestIO::sendfile('%s')",
+ filename));
+ }
+ else {
+ return rc;
+ }
+ }
+
+ if (!len) {
+ apr_finfo_t finfo;
+ apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
+ len = finfo.size;
+ if (offset) {
+ len -= offset;
+ }
+ }
+
+ /* flush any buffered modperl output */
+ {
+ modperl_config_req_t *rcfg = modperl_config_req_get(r);
+
+ MP_CHECK_WBUCKET_INIT("$r->rflush");
+ if (rcfg->wbucket->outcnt) {
+ MP_TRACE_o(MP_FUNC, "flushing %d bytes [%s]",
+ rcfg->wbucket->outcnt,
+ apr_pstrmemdup(rcfg->wbucket->pool,
+ rcfg->wbucket->outbuf,
+ rcfg->wbucket->outcnt));
+ MP_RUN_CROAK(modperl_wbucket_flush(rcfg->wbucket, TRUE),
+ "Apache2::RequestIO::sendfile");
+ }
+ }
+
+ rc = ap_send_fd(fp, r, offset, len, &nbytes);
+
+ /* apr_file_close(fp); */ /* do not do this */
+
+ if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
+ modperl_croak(aTHX_ rc, "Apache2::RequestIO::sendfile");
+ }
+
+ return rc;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/RequestRec/Apache2__RequestRec.h b/2_0_13/xs/Apache2/RequestRec/Apache2__RequestRec.h
new file mode 100644
index 0000000..4a85481
--- /dev/null
+++ b/2_0_13/xs/Apache2/RequestRec/Apache2__RequestRec.h
@@ -0,0 +1,155 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+const char *mpxs_Apache2__RequestRec_content_type(pTHX_ request_rec *r,
+ SV *type)
+{
+ const char *retval = r->content_type;
+
+ if (type) {
+ MP_dRCFG;
+ STRLEN len;
+ const char *val = SvPV(type, len);
+ ap_set_content_type(r, apr_pmemdup(r->pool, val, len+1));
+ MP_CGI_HEADER_PARSER_OFF(rcfg);
+ }
+
+ return retval;
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_content_languages(pTHX_ request_rec *r,
+ SV *languages)
+{
+ SV *retval = modperl_apr_array_header2avrv(aTHX_
+ r->content_languages);
+ if (languages) {
+ r->content_languages = modperl_avrv2apr_array_header(aTHX_
+ r->pool,
+ languages);
+ }
+ return retval;
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_proxyreq(pTHX_ request_rec *r, SV *val)
+{
+ int retval = r->proxyreq;
+
+ if (!val && !r->proxyreq &&
+ r->parsed_uri.scheme &&
+ !(r->parsed_uri.hostname &&
+ strEQ(r->parsed_uri.scheme, ap_http_scheme(r)) &&
+ ap_matches_request_vhost(r, r->parsed_uri.hostname,
+ r->parsed_uri.port_str ?
+ r->parsed_uri.port :
+ ap_default_port(r))))
+ {
+ retval = r->proxyreq = PROXYREQ_PROXY;
+ r->uri = r->unparsed_uri;
+ /* else mod_proxy will segfault */
+ r->filename = apr_pstrcat(r->pool, "modperl-proxy:", r->uri, NULL);
+ }
+
+ if (val) {
+ r->proxyreq = SvIV(val);
+ }
+
+ return retval;
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_subprocess_env(pTHX_ request_rec *r,
+ char *key, SV *val)
+{
+ /* if called in a void context with no arguments, just
+ * populate %ENV and stop.
+ */
+ if (key == NULL && GIMME_V == G_VOID) {
+ modperl_env_request_populate(aTHX_ r);
+ return &PL_sv_undef;
+ }
+
+ return modperl_table_get_set(aTHX_ r->subprocess_env,
+ key, val, TRUE);
+}
+
+static MP_INLINE
+apr_finfo_t *mpxs_Apache2__RequestRec_finfo(pTHX_ request_rec *r,
+ apr_finfo_t *finfo)
+{
+ if (finfo) {
+ r->finfo = *finfo;
+ }
+
+ return &r->finfo;
+}
+
+static MP_INLINE
+const char *mpxs_Apache2__RequestRec_handler(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ const char *RETVAL;
+ request_rec *r;
+ mpxs_usage_va_1(r, "$r->handler([$handler])");
+
+ RETVAL = (const char *)r->handler;
+
+ if (items == 2) {
+ if (SvPOK(*MARK)) {
+ char *new_handler = SvPVX(*MARK);
+ /* once inside a response phase, one should not try to
+ * switch response handler types, since they won't take
+ * any affect */
+ if (strEQ(modperl_callback_current_callback_get(),
+ "PerlResponseHandler")) {
+
+ switch (*new_handler) {
+ case 'm':
+ if (strEQ(new_handler, "modperl") &&
+ strEQ(RETVAL, "perl-script")) {
+ Perl_croak(aTHX_ "Can't switch from 'perl-script' "
+ "to 'modperl' response handler");
+ }
+ break;
+ case 'p':
+ if (strEQ(new_handler, "perl-script") &&
+ strEQ(RETVAL, "modperl")) {
+ Perl_croak(aTHX_ "Can't switch from 'modperl' "
+ "to 'perl-script' response handler");
+ }
+ break;
+ }
+ }
+
+ r->handler = (const char *)apr_pstrmemdup(r->pool, new_handler,
+ SvLEN(*MARK));
+ }
+ else {
+ Perl_croak(aTHX_ "the new_handler argument must be a string");
+ }
+ }
+
+ return RETVAL;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/RequestUtil/Apache2__RequestUtil.h b/2_0_13/xs/Apache2/RequestUtil/Apache2__RequestUtil.h
new file mode 100644
index 0000000..4433c88
--- /dev/null
+++ b/2_0_13/xs/Apache2/RequestUtil/Apache2__RequestUtil.h
@@ -0,0 +1,421 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_push_handlers(pTHX_ request_rec *r,
+ const char *name,
+ SV *sv)
+{
+ return modperl_handler_perl_add_handlers(aTHX_
+ r, NULL, r->server, r->pool,
+ name, sv,
+ MP_HANDLER_ACTION_PUSH);
+
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_set_handlers(pTHX_ request_rec *r,
+ const char *name,
+ SV *sv)
+{
+ return modperl_handler_perl_add_handlers(aTHX_
+ r, NULL, r->server, r->pool,
+ name, sv,
+ MP_HANDLER_ACTION_SET);
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_get_handlers(pTHX_ request_rec *r,
+ const char *name)
+{
+ MpAV **handp =
+ modperl_handler_get_handlers(r, NULL, r->server,
+ r->pool, name,
+ MP_HANDLER_ACTION_GET);
+
+ return modperl_handler_perl_get_handlers(aTHX_ handp, r->pool);
+}
+
+/*
+ * XXX: these three should be part of the apache api
+ * for protocol module helpers
+ */
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_new(pTHX_ SV *classname,
+ conn_rec *c,
+ SV *base_pool_sv)
+{
+ apr_pool_t *p, *base_pool;
+ request_rec *r;
+ server_rec *s = c->base_server;
+ SV *r_sv;
+
+ /* see: httpd-2.0/server/protocol.c:ap_read_request */
+
+ if (base_pool_sv) {
+ base_pool = mp_xs_sv2_APR__Pool(base_pool_sv);
+ }
+ else {
+ base_pool = c->pool;
+ }
+
+ apr_pool_create(&p, base_pool);
+ r = apr_pcalloc(p, sizeof(request_rec));
+
+ r->pool = p;
+ r->connection = c;
+ r->server = s;
+
+ r->request_time = apr_time_now();
+
+ r->user = NULL;
+ r->ap_auth_type = NULL;
+
+ r->allowed_methods = ap_make_method_list(p, 1);
+
+ r->headers_in = apr_table_make(p, 1);
+ r->subprocess_env = apr_table_make(r->pool, 1);
+ r->headers_out = apr_table_make(p, 1);
+ r->err_headers_out = apr_table_make(p, 1);
+ r->notes = apr_table_make(p, 1);
+
+ r->request_config = ap_create_request_config(p);
+
+ r->proto_output_filters = c->output_filters;
+ r->output_filters = r->proto_output_filters;
+ r->proto_input_filters = c->input_filters;
+ r->input_filters = r->proto_input_filters;
+
+ ap_run_create_request(r);
+
+ r->per_dir_config = s->lookup_defaults;
+
+ r->sent_bodyct = 0;
+ r->read_length = 0;
+ r->read_body = REQUEST_NO_BODY;
+ r->status = HTTP_OK;
+ r->the_request = "UNKNOWN";
+
+ r->hostname = s->server_hostname;
+
+ r->method = "GET";
+ r->method_number = M_GET;
+ r->uri = "/";
+ r->filename = (char *)ap_server_root_relative(p, r->uri);
+
+ r->assbackwards = 1;
+ r->protocol = "UNKNOWN";
+
+ r_sv = sv_setref_pv(newSV(0), "Apache2::RequestRec", (void*)r);
+
+ if (base_pool_sv) {
+ mpxs_add_pool_magic(r_sv, base_pool_sv);
+ }
+
+ return r_sv;
+}
+
+static MP_INLINE
+request_rec *mpxs_Apache2__RequestUtil_request(pTHX_ SV *classname, SV *svr)
+{
+ /* ignore classname */
+ return modperl_global_request(aTHX_ svr);
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_location_merge(request_rec *r,
+ char *location)
+{
+ apr_pool_t *p = r->pool;
+ server_rec *s = r->server;
+ core_server_config *sconf = ap_get_module_config(s->module_config,
+ &core_module);
+ ap_conf_vector_t **sec = (ap_conf_vector_t **)sconf->sec_url->elts;
+ int num_sec = sconf->sec_url->nelts;
+ int i;
+
+ for (i=0; i<num_sec; i++) {
+ core_dir_config *entry =
+ (core_dir_config *)ap_get_module_config(sec[i],
+ &core_module);
+
+ if (strEQ(entry->d, location)) {
+ r->per_dir_config =
+ ap_merge_per_dir_configs(p, s->lookup_defaults, sec[i]);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_set_basic_credentials(request_rec *r,
+ char *username,
+ char *password)
+{
+ char encoded[1024];
+ int elen;
+ char *auth_value, *auth_cat;
+
+ auth_cat = apr_pstrcat(r->pool,
+ username, ":", password, NULL);
+ elen = apr_base64_encode(encoded, auth_cat, strlen(auth_cat));
+ encoded[elen] = '\0';
+
+ auth_value = apr_pstrcat(r->pool, "Basic ", encoded, NULL);
+ apr_table_setn(r->headers_in, "Authorization", auth_value);
+}
+
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_no_cache(pTHX_ request_rec *r, SV *flag)
+{
+ int retval = r->no_cache;
+
+ if (flag) {
+ r->no_cache = (int)SvIV(flag);
+ }
+
+ if (r->no_cache) {
+ apr_table_setn(r->headers_out, "Pragma", "no-cache");
+ apr_table_setn(r->headers_out, "Cache-control", "no-cache");
+ }
+ else if (flag) { /* only unset if $r->no_cache(0) */
+ apr_table_unset(r->headers_out, "Pragma");
+ apr_table_unset(r->headers_out, "Cache-control");
+ }
+
+ return retval;
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_pnotes(pTHX_ request_rec *r, SV *key, SV *val)
+{
+ MP_dRCFG;
+
+ if (!rcfg) {
+ return &PL_sv_undef;
+ }
+
+ return modperl_pnotes(aTHX_ &rcfg->pnotes, key, val, r->pool);
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_pnotes_kill(pTHX_ request_rec *r)
+{
+ MP_dRCFG;
+
+ if (!rcfg) {
+ return;
+ }
+
+ modperl_pnotes_kill(&rcfg->pnotes);
+}
+
+#define mpxs_Apache2__RequestRec_dir_config(r, key, sv_val) \
+ modperl_dir_config(aTHX_ r, r->server, key, sv_val)
+
+#define mpxs_Apache2__RequestRec_slurp_filename(r, tainted) \
+ modperl_slurp_filename(aTHX_ r, tainted)
+
+static MP_INLINE
+char *mpxs_Apache2__RequestRec_location(request_rec *r)
+{
+ MP_dDCFG;
+
+ return dcfg->location;
+}
+
+typedef struct {
+ PerlInterpreter *perl;
+ SV *sv;
+} sv_str_header_t;
+
+static int sv_str_header(void *arg, const char *k, const char *v)
+{
+ sv_str_header_t *svh = (sv_str_header_t *)arg;
+ dTHXa(svh->perl);
+ Perl_sv_catpvf(aTHX_ svh->sv, "%s: %s\n", k, v);
+ return 1;
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__RequestRec_as_string(pTHX_ request_rec *r)
+{
+ sv_str_header_t svh;
+#ifdef USE_ITHREADS
+ svh.perl = aTHX;
+#endif
+
+ svh.sv = newSVpv(r->the_request, 0);
+
+ sv_catpvn(svh.sv, "\n", 1);
+
+ apr_table_do((int (*) (void *, const char *, const char *))
+ sv_str_header, (void *) &svh, r->headers_in, NULL);
+
+ Perl_sv_catpvf(aTHX_ svh.sv, "\n%s %s\n", r->protocol, r->status_line);
+
+ apr_table_do((int (*) (void *, const char *, const char *))
+ sv_str_header, (void *) &svh, r->headers_out, NULL);
+ apr_table_do((int (*) (void *, const char *, const char *))
+ sv_str_header, (void *) &svh, r->err_headers_out, NULL);
+
+ sv_catpvn(svh.sv, "\n", 1);
+
+ return svh.sv;
+}
+
+static MP_INLINE
+int mpxs_Apache2__RequestRec_is_perl_option_enabled(pTHX_ request_rec *r,
+ const char *name)
+{
+ return modperl_config_is_perl_option_enabled(aTHX_ r, r->server, name);
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_add_config(pTHX_ request_rec *r, SV *lines,
+ int override, char *path,
+ int override_options)
+{
+ const char *errmsg = modperl_config_insert_request(aTHX_ r, lines,
+ override, path,
+ override_options);
+ if (errmsg) {
+ Perl_croak(aTHX_ "$r->add_config() has failed: %s", errmsg);
+ }
+}
+
+/* in order to ensure that s->document_root doesn't get corrupted by
+ * modperl users setting its value, restore the original value at the
+ * end of each request */
+struct mp_docroot_info {
+ const char **docroot;
+ const char *original;
+};
+
+static apr_status_t restore_docroot(void *data)
+{
+ struct mp_docroot_info *di = (struct mp_docroot_info *)data;
+ *di->docroot = di->original;
+ return APR_SUCCESS;
+}
+
+static MP_INLINE
+const char *mpxs_Apache2__RequestRec_document_root(pTHX_ request_rec *r,
+ SV *new_root)
+{
+ const char *retval = ap_document_root(r);
+
+ if (new_root) {
+ struct mp_docroot_info *di;
+ core_server_config *conf;
+ MP_CROAK_IF_THREADS_STARTED("setting $r->document_root");
+ conf = ap_get_module_config(r->server->module_config,
+ &core_module);
+ di = apr_palloc(r->pool, sizeof *di);
+ di->docroot = &conf->ap_document_root;
+ di->original = conf->ap_document_root;
+ apr_pool_cleanup_register(r->pool, di, restore_docroot,
+ restore_docroot);
+
+ conf->ap_document_root = apr_pstrdup(r->pool, SvPV_nolen(new_root));
+ }
+
+ return retval;
+}
+
+static apr_status_t child_terminate(void *data) {
+ apr_pool_t *pool = (apr_pool_t *)data;
+
+ /* On the first pass, re-register so we end up last */
+ if (data) {
+ apr_pool_cleanup_register(pool, NULL, child_terminate,
+ apr_pool_cleanup_null);
+ }
+ else {
+ exit(0);
+ }
+ return APR_SUCCESS;
+}
+
+static MP_INLINE
+void mpxs_Apache2__RequestRec_child_terminate(pTHX_ request_rec *r)
+{
+ MP_CROAK_IF_THREADED_MPM("$r->child_terminate")
+ apr_pool_cleanup_register(r->pool, r->pool, child_terminate,
+ apr_pool_cleanup_null);
+}
+
+
+
+static MP_INLINE
+apr_status_t mpxs_ap_register_auth_provider(pTHX_ I32 items, SV **MARK, SV **SP)
+{
+ apr_pool_t *pool;
+ const char *provider_group;
+ const char *provider_name;
+ const char *provider_version;
+ SV *callback1;
+ SV *callback2 = NULL;
+ int type;
+
+ if (items != 7)
+ Perl_croak(aTHX_ "pool, provider_group, provider_name, "
+ "provider_version, callback1, callback2, type");
+
+ if (SvROK(*MARK) && sv_derived_from(*MARK, "APR::Pool")) {
+ IV tmp = SvIV((SV*)SvRV(*MARK));
+ if (tmp == 0) {
+ Perl_croak(aTHX_ "invalid pool object (already destroyed?)");
+ }
+ pool = INT2PTR(APR__Pool, tmp);
+ }
+ else {
+ Perl_croak(aTHX_ SvROK(*MARK) ?
+ "pool is not of type APR::Pool" :
+ "pool is not a blessed reference");
+ }
+
+ MARK++;
+ provider_group = (const char *)SvPV_nolen(*MARK);
+ MARK++;
+ provider_name = (const char *)SvPV_nolen(*MARK);
+ MARK++;
+ provider_version = (const char *)SvPV_nolen(*MARK);
+ MARK++;
+ callback1 = newSVsv(*MARK);
+ MARK++;
+ callback2 = NULL;
+ if (SvROK(*MARK)) {
+ callback2 = newSVsv(*MARK);
+ }
+ MARK++;
+ type = (int)SvIV(*MARK);
+
+ return modperl_register_auth_provider(pool, provider_group, provider_name,
+ provider_version, callback1,
+ callback2, type);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Response/Apache2__Response.h b/2_0_13/xs/Apache2/Response/Apache2__Response.h
new file mode 100644
index 0000000..6bd03be
--- /dev/null
+++ b/2_0_13/xs/Apache2/Response/Apache2__Response.h
@@ -0,0 +1,48 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* XXX: this should probably named $r->cgi_header_parse
+ * and send_cgi_header an alias in Apache2::compat
+ */
+#define mpxs_Apache2__RequestRec_send_cgi_header(r, sv) \
+{ \
+ MP_dRCFG; \
+ STRLEN len; \
+ const char *bodytext; \
+ MP_CGI_HEADER_PARSER_OFF(rcfg); \
+ SvPV_force(sv, len); \
+ modperl_cgi_header_parse(r, SvPVX(sv), (apr_size_t*)&len, &bodytext); \
+ if (len) {\
+ MP_CHECK_WBUCKET_INIT("$r->send_cgi_header"); \
+ modperl_wbucket_write(aTHX_ rcfg->wbucket, bodytext, &len); \
+ } \
+}
+
+static MP_INLINE void
+mpxs_Apache2__RequestRec_set_last_modified(request_rec *r, apr_time_t mtime)
+{
+ if (mtime) {
+ ap_update_mtime(r, mtime);
+ }
+ ap_set_last_modified(r);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/ServerRec/Apache2__ServerRec.h b/2_0_13/xs/Apache2/ServerRec/Apache2__ServerRec.h
new file mode 100644
index 0000000..91d944a
--- /dev/null
+++ b/2_0_13/xs/Apache2/ServerRec/Apache2__ServerRec.h
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || AP_SERVER_MINORVERSION_NUMBER>=3
+#define loglevel log.level
+
+static MP_INLINE
+int mpxs_Apache2__ServerRec_is_virtual(pTHX_ server_rec *s, SV *val)
+{
+ int retval = s->is_virtual;
+
+ if (val) {
+ s->is_virtual = SvIV(val);
+ }
+
+ return retval;
+}
+
+#endif
diff --git a/2_0_13/xs/Apache2/ServerRec/ServerRec_pm b/2_0_13/xs/Apache2/ServerRec/ServerRec_pm
new file mode 100644
index 0000000..5a606cc
--- /dev/null
+++ b/2_0_13/xs/Apache2/ServerRec/ServerRec_pm
@@ -0,0 +1,4 @@
+use Exporter ();
+use Apache2::Log (); # Apache2::ServerRec::loads warn
+@Apache2::ServerRec::EXPORT_OK = qw(warn);
+*Apache2::ServerRec::import = \&Exporter::import;
diff --git a/2_0_13/xs/Apache2/ServerUtil/Apache2__ServerUtil.h b/2_0_13/xs/Apache2/ServerUtil/Apache2__ServerUtil.h
new file mode 100644
index 0000000..f52ed0a
--- /dev/null
+++ b/2_0_13/xs/Apache2/ServerUtil/Apache2__ServerUtil.h
@@ -0,0 +1,227 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
+#include "unixd.h"
+#endif
+
+#define mpxs_Apache2__ServerUtil_restart_count modperl_restart_count
+
+#define mpxs_Apache2__ServerRec_method_register(s, methname) \
+ ap_method_register(s->process->pconf, methname);
+
+#define mpxs_Apache2__ServerRec_add_version_component(s, component) \
+ ap_add_version_component(s->process->pconf, component);
+
+/* XXX: the mpxs_cleanup_t and mpxs_cleanup_run are almost dups with
+ * code in APR__Pool.h (minus interpr member which is not used
+ * here. They should be moved to modperl_common_util - the problem is
+ * modperl_interp_t *, which can't live in modperl_common_* since it
+ * creates a dependency on mod_perl. A possible solution is to use
+ * void * for that slot and cast it to modperl_interp_t * when used
+ */
+
+typedef struct {
+ SV *cv;
+ SV *arg;
+ apr_pool_t *p;
+#ifdef USE_ITHREADS
+ PerlInterpreter *perl;
+#endif
+} mpxs_cleanup2_t;
+
+/**
+ * callback wrapper for Perl cleanup subroutines
+ * @param data internal storage
+ */
+static apr_status_t mpxs_cleanup_run(void *data)
+{
+ int count;
+ mpxs_cleanup2_t *cdata = (mpxs_cleanup2_t *)data;
+#ifdef USE_ITHREADS
+ dTHXa(cdata->perl);
+#endif
+ dSP;
+#ifdef USE_ITHREADS
+ PERL_SET_CONTEXT(aTHX);
+#endif
+
+ ENTER;SAVETMPS;
+ PUSHMARK(SP);
+ if (cdata->arg) {
+ XPUSHs(cdata->arg);
+ }
+ PUTBACK;
+
+ save_gp(PL_errgv, 1); /* local *@ */
+ count = call_sv(cdata->cv, G_SCALAR|G_EVAL);
+
+ SPAGAIN;
+
+ if (count == 1) {
+ (void)POPs; /* the return value is ignored */
+ }
+
+ if (SvTRUE(ERRSV)) {
+ Perl_warn(aTHX_ "Apache2::ServerUtil: cleanup died: %s",
+ SvPV_nolen(ERRSV));
+ }
+
+ PUTBACK;
+ FREETMPS;LEAVE;
+
+ SvREFCNT_dec(cdata->cv);
+ if (cdata->arg) {
+ SvREFCNT_dec(cdata->arg);
+ }
+
+ /* the return value is ignored by apr_pool_destroy anyway */
+ return APR_SUCCESS;
+}
+
+/* this cleanups registered by this function are run only by the
+ * parent interpreter */
+static MP_INLINE
+void mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register(pTHX_ SV *cv,
+ SV *arg)
+{
+ mpxs_cleanup2_t *data;
+ apr_pool_t *p;
+
+ MP_CROAK_IF_POST_POST_CONFIG_PHASE("server_shutdown_cleanup_register");
+
+ p = modperl_server_user_pool();
+ /* must use modperl_server_user_pool here to make sure that it's run
+ * before parent perl is destroyed */
+ data = (mpxs_cleanup2_t *)apr_pcalloc(p, sizeof(*data));
+ data->cv = SvREFCNT_inc(cv);
+ data->arg = arg ? SvREFCNT_inc(arg) : (SV *)NULL;
+ data->p = p;
+#ifdef USE_ITHREADS
+ data->perl = aTHX;
+#endif /* USE_ITHREADS */
+
+ apr_pool_cleanup_register(p, data, mpxs_cleanup_run,
+ apr_pool_cleanup_null);
+}
+
+static MP_INLINE
+int mpxs_Apache2__ServerRec_push_handlers(pTHX_ server_rec *s,
+ const char *name,
+ SV *sv)
+{
+ return modperl_handler_perl_add_handlers(aTHX_
+ NULL, NULL, s,
+ s->process->pconf,
+ name, sv,
+ MP_HANDLER_ACTION_PUSH);
+
+}
+
+static MP_INLINE
+int mpxs_Apache2__ServerRec_set_handlers(pTHX_ server_rec *s,
+ const char *name,
+ SV *sv)
+{
+ return modperl_handler_perl_add_handlers(aTHX_
+ NULL, NULL, s,
+ s->process->pconf,
+ name, sv,
+ MP_HANDLER_ACTION_SET);
+}
+
+static MP_INLINE
+SV *mpxs_Apache2__ServerRec_get_handlers(pTHX_ server_rec *s,
+ const char *name)
+{
+ MpAV **handp =
+ modperl_handler_get_handlers(NULL, NULL, s,
+ s->process->pconf, name,
+ MP_HANDLER_ACTION_GET);
+
+ return modperl_handler_perl_get_handlers(aTHX_ handp,
+ s->process->pconf);
+}
+
+#define mpxs_Apache2__ServerRec_dir_config(s, key, sv_val) \
+ modperl_dir_config(aTHX_ NULL, s, key, sv_val)
+
+#define mpxs_Apache2__ServerUtil_server(classname) modperl_global_get_server_rec()
+
+#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
+#define mpxs_Apache2__ServerUtil_user_id(classname) ap_unixd_config.user_id
+#define mpxs_Apache2__ServerUtil_group_id(classname) ap_unixd_config.group_id
+#else
+#define mpxs_Apache2__ServerUtil_user_id(classname) 0
+#define mpxs_Apache2__ServerUtil_group_id(classname) 0
+#endif
+
+static MP_INLINE
+int mpxs_Apache2__ServerRec_is_perl_option_enabled(pTHX_ server_rec *s,
+ const char *name)
+{
+ return modperl_config_is_perl_option_enabled(aTHX_ NULL, s, name);
+}
+
+
+static MP_INLINE
+void mpxs_Apache2__ServerRec_add_config(pTHX_ server_rec *s, SV *lines)
+{
+ const char *errmsg;
+
+ MP_CROAK_IF_POST_POST_CONFIG_PHASE("$s->add_config");
+
+ errmsg = modperl_config_insert_server(aTHX_ s, lines);
+ if (errmsg) {
+ Perl_croak(aTHX_ "$s->add_config() has failed: %s", errmsg);
+ }
+}
+
+#define mpxs_Apache2__ServerRec_get_server_banner \
+ ap_get_server_banner()
+#define mpxs_Apache2__ServerRec_get_server_description \
+ ap_get_server_description()
+#define mpxs_Apache2__ServerRec_get_server_version \
+ ap_get_server_version()
+
+static void mpxs_Apache2__ServerUtil_BOOT(pTHX)
+{
+ newCONSTSUB(PL_defstash, "Apache2::ServerUtil::server_root",
+ newSVpv(ap_server_root, 0));
+
+ newCONSTSUB(PL_defstash, "Apache2::ServerUtil::get_server_built",
+ newSVpv(ap_get_server_built(), 0));
+}
+
+#if AP_SERVER_MAJORVERSION_NUMBER>2 || \
+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3)
+static MP_INLINE
+int mpxs_Apache2__ServerRec_loglevel(pTHX_ server_rec *s, int loglevel)
+{
+ if (loglevel) {
+ s->log.level = loglevel;
+ }
+
+ return s->log.level;
+}
+#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/SubProcess/Apache2__SubProcess.h b/2_0_13/xs/Apache2/SubProcess/Apache2__SubProcess.h
new file mode 100644
index 0000000..4db7d4a
--- /dev/null
+++ b/2_0_13/xs/Apache2/SubProcess/Apache2__SubProcess.h
@@ -0,0 +1,225 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../../APR/PerlIO/modperl_apr_perlio.h"
+
+#ifndef MP_SOURCE_SCAN
+#include "apr_optional.h"
+
+static APR_OPTIONAL_FN_TYPE(modperl_apr_perlio_apr_file_to_glob) *apr_file_to_glob;
+#endif
+
+/* XXX: probably needs a lot more error checkings */
+
+typedef struct {
+ apr_int32_t in_pipe;
+ apr_int32_t out_pipe;
+ apr_int32_t err_pipe;
+ apr_cmdtype_e cmd_type;
+} exec_info;
+
+#undef FAILED /* win32 defines a macro with this name */
+#define FAILED(command) ((rc = command) != APR_SUCCESS)
+
+#define SET_TIMEOUT(fp) \
+ apr_file_pipe_timeout_set(fp, \
+ (int)(apr_time_from_sec(r->server->timeout)))
+
+static int modperl_spawn_proc_prog(pTHX_
+ request_rec *r,
+ const char *command,
+ const char ***argv,
+ apr_file_t **script_in,
+ apr_file_t **script_out,
+ apr_file_t **script_err)
+{
+ exec_info e_info;
+ apr_pool_t *p;
+ const char * const *env;
+
+ apr_procattr_t *procattr;
+ apr_proc_t *procnew;
+ apr_status_t rc = APR_SUCCESS;
+
+ e_info.in_pipe = APR_CHILD_BLOCK;
+ e_info.out_pipe = APR_CHILD_BLOCK;
+ e_info.err_pipe = APR_CHILD_BLOCK;
+ e_info.cmd_type = APR_PROGRAM;
+
+ p = r->main ? r->main->pool : r->pool;
+
+ *script_out = *script_in = *script_err = NULL;
+
+ env = (const char * const *)ap_create_environment(p, r->subprocess_env);
+
+ if (FAILED(apr_procattr_create(&procattr, p)) ||
+ FAILED(apr_procattr_io_set(procattr, e_info.in_pipe,
+ e_info.out_pipe, e_info.err_pipe)) ||
+ FAILED(apr_procattr_dir_set(procattr,
+ ap_make_dirstr_parent(r->pool,
+ r->filename))) ||
+ FAILED(apr_procattr_cmdtype_set(procattr, e_info.cmd_type)))
+ {
+ /* Something bad happened, tell the world. */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r,
+ "couldn't set child process attributes: %s",
+ r->filename);
+ return rc;
+ }
+
+ procnew = apr_pcalloc(p, sizeof(*procnew));
+ if (FAILED(ap_os_create_privileged_process(r, procnew, command,
+ *argv, env, procattr, p)))
+ {
+ /* Bad things happened. Everyone should have cleaned up. */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r,
+ "couldn't create child process: %d: %s",
+ rc, r->filename);
+ return rc;
+ }
+
+ apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);
+
+ if (!(*script_in = procnew->in)) {
+ Perl_croak(aTHX_ "broken program-in stream");
+ return APR_EBADF;
+ }
+ SET_TIMEOUT(*script_in);
+
+ if (!(*script_out = procnew->out)) {
+ Perl_croak(aTHX_ "broken program-out stream");
+ return APR_EBADF;
+ }
+ SET_TIMEOUT(*script_out);
+
+ if (!(*script_err = procnew->err)) {
+ Perl_croak(aTHX_ "broken program-err stream");
+ return APR_EBADF;
+ }
+ SET_TIMEOUT(*script_err);
+
+ return rc;
+}
+
+#define PUSH_FILE_GLOB(fp, type) \
+ PUSHs(apr_file_to_glob(aTHX_ fp, r->pool, type))
+
+#define PUSH_FILE_GLOB_READ(fp) \
+ PUSH_FILE_GLOB(fp, MODPERL_APR_PERLIO_HOOK_READ)
+
+#define PUSH_FILE_GLOB_WRITE(fp) \
+ PUSH_FILE_GLOB(fp, MODPERL_APR_PERLIO_HOOK_WRITE)
+
+#define CLOSE_SCRIPT_STD(stream) \
+ rc = apr_file_close(stream); \
+ if (rc != APR_SUCCESS) { \
+ XSRETURN_UNDEF; \
+ }
+
+MP_STATIC XS(MPXS_modperl_spawn_proc_prog)
+{
+ dXSARGS;
+ const char *usage = "Usage: spawn_proc_prog($r, $command, [\\@argv])";
+
+ if (items < 2) {
+ Perl_croak(aTHX_ "%s", usage);
+ }
+
+ SP -= items;
+ {
+ apr_file_t *script_in, *script_out, *script_err;
+ apr_status_t rc;
+ const char **argv;
+ int i=0;
+ AV *av_argv = (AV *)NULL;
+ I32 len=-1, av_items=0;
+ request_rec *r = modperl_xs_sv2request_rec(aTHX_ ST(0), NULL, cv);
+ const char *command = (const char *)SvPV_nolen(ST(1));
+
+ if (items == 3) {
+ if (SvROK(ST(2)) && SvTYPE(SvRV(ST(2))) == SVt_PVAV) {
+ av_argv = (AV*)SvRV(ST(2));
+ len = AvFILLp(av_argv);
+ av_items = len+1;
+ }
+ else {
+ Perl_croak(aTHX_ "%s", usage);
+ }
+ }
+
+ /* ap_os_create_privileged_process expects ARGV as char
+ * **argv, with terminating NULL and the program itself as a
+ * first item.
+ */
+ argv = apr_palloc(r->pool, (av_items + 2) * sizeof(char *));
+ argv[0] = command;
+ if (av_argv) {
+ for (i = 0; i <= len; i++) {
+ argv[i+1] = (const char *)SvPV_nolen(AvARRAY(av_argv)[i]);
+ }
+ }
+ argv[i+1] = NULL;
+#if 0
+ for (i=0; i<=len+2; i++) {
+ Perl_warn(aTHX_ "arg: %d %s\n",
+ i, argv[i] ? argv[i] : "NULL");
+ }
+#endif
+ rc = modperl_spawn_proc_prog(aTHX_ r, command, &argv,
+ &script_in, &script_out,
+ &script_err);
+
+ if (rc == APR_SUCCESS) {
+ /* XXX: apr_file_to_glob should be set once in the BOOT: section */
+ apr_file_to_glob =
+ APR_RETRIEVE_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_glob);
+
+ if (GIMME_V == G_VOID) {
+ CLOSE_SCRIPT_STD(script_in);
+ CLOSE_SCRIPT_STD(script_out);
+ CLOSE_SCRIPT_STD(script_err);
+ XSRETURN_EMPTY;
+ }
+ else if (GIMME_V == G_SCALAR) {
+ /* XXX: need to do lots of error checking before
+ * putting the object on the stack
+ */
+ EXTEND(SP, 1);
+ PUSH_FILE_GLOB_READ(script_out);
+ CLOSE_SCRIPT_STD(script_in);
+ CLOSE_SCRIPT_STD(script_err);
+ }
+ else {
+ EXTEND(SP, 3);
+ PUSH_FILE_GLOB_WRITE(script_in);
+ PUSH_FILE_GLOB_READ(script_out);
+ PUSH_FILE_GLOB_READ(script_err);
+ }
+ }
+ else {
+ XSRETURN_UNDEF;
+ }
+ }
+
+ PUTBACK;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/SubProcess/SubProcess_pm b/2_0_13/xs/Apache2/SubProcess/SubProcess_pm
new file mode 100644
index 0000000..92da457
--- /dev/null
+++ b/2_0_13/xs/Apache2/SubProcess/SubProcess_pm
@@ -0,0 +1 @@
+use APR::PerlIO ();
diff --git a/2_0_13/xs/Apache2/SubRequest/Apache2__SubRequest.h b/2_0_13/xs/Apache2/SubRequest/Apache2__SubRequest.h
new file mode 100644
index 0000000..debfa70
--- /dev/null
+++ b/2_0_13/xs/Apache2/SubRequest/Apache2__SubRequest.h
@@ -0,0 +1,40 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE int mpxs_ap_run_sub_req(pTHX_ request_rec *r)
+{
+ /* need to flush main request output buffer if any
+ * before running any subrequests, else we get subrequest
+ * output before anything already written in the main request
+ */
+
+ if (r->main) {
+ modperl_config_req_t *rcfg = modperl_config_req_get(r->main);
+ if (rcfg->wbucket) {
+ MP_RUN_CROAK(modperl_wbucket_flush(rcfg->wbucket, FALSE),
+ "Apache2::SubRequest::run");
+ }
+ }
+
+ return ap_run_sub_req(r);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/URI/Apache2__URI.h b/2_0_13/xs/Apache2/URI/Apache2__URI.h
new file mode 100644
index 0000000..5c33c26
--- /dev/null
+++ b/2_0_13/xs/Apache2/URI/Apache2__URI.h
@@ -0,0 +1,47 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+apr_uri_t *mpxs_Apache2__RequestRec_parsed_uri(request_rec *r)
+{
+ modperl_uri_t *uri = modperl_uri_new(r->pool);
+
+ uri->uri = r->parsed_uri;
+ uri->path_info = r->path_info;
+
+ return (apr_uri_t *)uri;
+}
+
+static MP_INLINE char *mpxs_ap_unescape_url(pTHX_ SV *url)
+{
+ int status;
+ STRLEN n_a;
+
+ (void)SvPV_force(url, n_a);
+
+ if ((status = ap_unescape_url(SvPVX(url))) == OK) {
+ SvCUR_set(url, strlen(SvPVX(url)));
+ }
+
+ return SvPVX(url);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Apache2/Util/Apache2__Util.h b/2_0_13/xs/Apache2/Util/Apache2__Util.h
new file mode 100644
index 0000000..19220d0
--- /dev/null
+++ b/2_0_13/xs/Apache2/Util/Apache2__Util.h
@@ -0,0 +1,25 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define TIME_NOW apr_time_now()
+#define DEFAULT_TIME_FORMAT "%a, %d %b %Y %H:%M:%S %Z"
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/Makefile.PL b/2_0_13/xs/Makefile.PL
new file mode 100644
index 0000000..d82becc
--- /dev/null
+++ b/2_0_13/xs/Makefile.PL
@@ -0,0 +1,7 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => "ModPerl::XS",
+ VERSION => '0.01'
+);
diff --git a/2_0_13/xs/ModPerl/Const/Const.pm b/2_0_13/xs/ModPerl/Const/Const.pm
new file mode 100644
index 0000000..2b9632d
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Const/Const.pm
@@ -0,0 +1,56 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package ModPerl::Const;
+
+use DynaLoader ();
+
+our $VERSION = do { require mod_perl2; $mod_perl2::VERSION };
+our @ISA = qw(DynaLoader);
+
+#dlopen("Const.so", RTDL_GLOBAL);
+#XXX: dl_dlopen.xs check isn't portable; works for hpux
+# - on aix this is dl_aix.xs, and depending on release, RTDL_GLOBAL is
+# available or not, e.g. 4.3 doesn't have it in the headers, while
+# 5.1 does have it
+# - from looking at ext/DynaLoader/dl_*.xs when 0x01 is used when it's
+# not supported perl issues a warning and passes the right flag to dlopen
+# - currently (patchlevel 18958) dl_aix.xs always issues a warning
+# even when RTDL_GLOBAL is available, patch submitted to p5p
+use Config ();
+use constant DL_GLOBAL =>
+ ( $Config::Config{dlsrc} eq 'dl_dlopen.xs' && $^O ne 'openbsd' ) ? 0x01 : 0x0;
+sub dl_load_flags { DL_GLOBAL }
+
+#only bootstrap for use outside of mod_perl
+unless (defined &ModPerl::Const::compile) {
+ __PACKAGE__->bootstrap($VERSION);
+}
+
+sub import {
+ my $class = shift;
+ my $arg;
+
+ if ($_[0] and $_[0] =~ /^-compile/) {
+ $arg = shift; #just compile the constants subs, export nothing
+ }
+
+ $arg ||= scalar caller; #compile and export into caller's namespace
+
+ $class->compile($arg, @_ ? @_ : ':common');
+}
+
+1;
diff --git a/2_0_13/xs/ModPerl/Const/Const.xs b/2_0_13/xs/ModPerl/Const/Const.xs
new file mode 100644
index 0000000..85b0a32
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Const/Const.xs
@@ -0,0 +1,47 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_perl.h"
+#include "modperl_const.h"
+
+#ifndef WIN32
+/* FIXME: To define extern perl_module to something so Const.so can be
+ * loaded later. Without this code, loading Const.so fails with
+ * undefined_symbol: perl_module. (Windows does not need this since it
+ * explicitly links against mod_perl.lib anyway.)
+ */
+module AP_MODULE_DECLARE_DATA perl_module = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ NULL, /* table of config file commands */
+ NULL, /* register hooks */
+};
+#endif
+
+MODULE = ModPerl::Const PACKAGE = ModPerl::Const
+
+PROTOTYPES: disable
+
+BOOT:
+#XXX:
+#currently used just for {APR,Apache}/Const.{so,dll} to lookup
+#XS_modperl_const_compile
+#linking is fun.
+newXS("ModPerl::Const::compile", XS_modperl_const_compile, __FILE__);
+
diff --git a/2_0_13/xs/ModPerl/Const/Makefile.PL b/2_0_13/xs/ModPerl/Const/Makefile.PL
new file mode 100644
index 0000000..a7a1838
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Const/Makefile.PL
@@ -0,0 +1,32 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+my $srcdir = '../../../src/modules/perl';
+#link these two into Const.so so constants can be used outside of httpd
+my @names = map { "modperl_$_" } qw(const constants);
+my(@obj, @clean, %src);
+
+for (@names) {
+ push @obj, join '.', $_, 'o';
+ my $cfile = join '.', $_, 'c';
+ push @clean, $cfile;
+ $src{$cfile} = "$srcdir/$cfile";
+}
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => 'ModPerl::Const',
+ VERSION_FROM => 'Const.pm',
+ OBJECT => "Const.o @obj",
+ clean => { FILES => "@clean" },
+);
+
+sub MY::postamble {
+ my $self = shift;
+ my $string = $self->ModPerl::BuildMM::MY::postamble;
+
+ $string .= join '', map {
+ "$_: $src{$_}\n\t\$(CP) $src{$_} .\n";
+ } sort keys %src;
+
+ return $string;
+}
diff --git a/2_0_13/xs/ModPerl/Global/ModPerl__Global.h b/2_0_13/xs/ModPerl/Global/ModPerl__Global.h
new file mode 100644
index 0000000..0d76ceb
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Global/ModPerl__Global.h
@@ -0,0 +1,69 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+typedef void (*mpxs_special_list_do_t)(pTHX_ modperl_modglobal_key_t *,
+ const char *, I32);
+
+static int mpxs_special_list_do(pTHX_ const char *name,
+ SV *package,
+ mpxs_special_list_do_t func)
+{
+ STRLEN packlen;
+ char *packname;
+ modperl_modglobal_key_t *gkey = modperl_modglobal_lookup(aTHX_ name);
+
+ if (!gkey) {
+ return FALSE;
+ }
+
+ packname = SvPV(package, packlen);
+
+ func(aTHX_ gkey, packname, packlen);
+
+ return TRUE;
+}
+
+static
+MP_INLINE int mpxs_ModPerl__Global_special_list_call(pTHX_ const char *name,
+ SV *package)
+{
+ return mpxs_special_list_do(aTHX_ name, package,
+ modperl_perl_global_avcv_call);
+}
+
+static
+MP_INLINE int mpxs_ModPerl__Global_special_list_clear(pTHX_ const char *name,
+ SV *package)
+{
+ return mpxs_special_list_do(aTHX_ name, package,
+ modperl_perl_global_avcv_clear);
+}
+
+static
+MP_INLINE int mpxs_ModPerl__Global_special_list_register(pTHX_
+ const char *name,
+ SV *package)
+{
+ return mpxs_special_list_do(aTHX_ name, package,
+ modperl_perl_global_avcv_register);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/ModPerl/Interpreter/ModPerl__Interpreter.h b/2_0_13/xs/ModPerl/Interpreter/ModPerl__Interpreter.h
new file mode 100644
index 0000000..c3f735e
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Interpreter/ModPerl__Interpreter.h
@@ -0,0 +1,28 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static MP_INLINE
+modperl_interp_t *mpxs_ModPerl__Interpreter_current(pTHX_ SV *class)
+{
+ return modperl_thx_interp_get(aTHX);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/ModPerl/Makefile.PL b/2_0_13/xs/ModPerl/Makefile.PL
new file mode 100644
index 0000000..1e7f50e
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Makefile.PL
@@ -0,0 +1,7 @@
+use lib qw(../lib);
+use ModPerl::BuildMM ();
+
+ModPerl::BuildMM::WriteMakefile(
+ NAME => "ModPerl",
+ VERSION => '0.01'
+);
diff --git a/2_0_13/xs/ModPerl/Util/ModPerl__Util.h b/2_0_13/xs/ModPerl/Util/ModPerl__Util.h
new file mode 100644
index 0000000..3e09070
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Util/ModPerl__Util.h
@@ -0,0 +1,49 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef USE_ITHREADS
+#define mpxs_ModPerl__Util_current_perl_id() \
+ Perl_newSVpvf(aTHX_ "0x%lx", (unsigned long)aTHX)
+#else
+#define mpxs_ModPerl__Util_current_perl_id() \
+ Perl_newSVpvf(aTHX_ "0x%lx", (unsigned long)0)
+#endif
+
+static MP_INLINE void mpxs_ModPerl__Util_untaint(pTHX_ I32 items,
+ SV **MARK, SV **SP)
+{
+ if (!PL_tainting) {
+ return;
+ }
+ while (MARK <= SP) {
+ sv_untaint(*MARK++);
+ }
+}
+
+#define mpxs_ModPerl__Util_current_callback \
+ modperl_callback_current_callback_get
+
+#define mpxs_ModPerl__Util_unload_package_xs(pkg) \
+ modperl_package_unload(aTHX_ pkg)
+
+/* ModPerl::Util::exit lives in mod_perl.so, see modperl_perl.c */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/ModPerl/Util/Util_pm b/2_0_13/xs/ModPerl/Util/Util_pm
new file mode 100644
index 0000000..365661e
--- /dev/null
+++ b/2_0_13/xs/ModPerl/Util/Util_pm
@@ -0,0 +1,63 @@
+#Extra stuff
+
+our $DEFAULT_UNLOAD_METHOD ||= "unload_package_pp";
+
+sub unload_package {
+ goto &$DEFAULT_UNLOAD_METHOD;
+}
+
+sub unload_package_pp {
+ my $package = shift;
+ no strict 'refs';
+ my $tab = \%{ $package . '::' };
+
+ # below we assign to a symbol first before undef'ing it, to avoid
+ # nuking aliases. If we undef directly we may undef not only the
+ # alias but the original function as well
+
+ for (keys %$tab) {
+ #Skip sub stashes
+ next if /::$/;
+
+ my $fullname = join '::', $package, $_;
+ # code/hash/array/scalar might be imported make sure the gv
+ # does not point elsewhere before undefing each
+ if (%$fullname) {
+ *{$fullname} = {};
+ undef %$fullname;
+ }
+ if (@$fullname) {
+ *{$fullname} = [];
+ undef @$fullname;
+ }
+ if ($$fullname) {
+ my $tmp; # argh, no such thing as an anonymous scalar
+ *{$fullname} = \$tmp;
+ undef $$fullname;
+ }
+ if (defined &$fullname) {
+ no warnings;
+ local $^W = 0;
+ if (defined(my $p = prototype $fullname)) {
+ *{$fullname} = eval "sub ($p) {}";
+ }
+ else {
+ *{$fullname} = sub {};
+ }
+ undef &$fullname;
+ }
+ if (*{$fullname}{IO}) {
+ local $@;
+ eval {
+ if (fileno $fullname) {
+ close $fullname;
+ }
+ };
+ }
+ }
+
+ #Wipe from %INC
+ $package =~ s[::][/]g;
+ $package .= '.pm';
+ delete $INC{$package};
+}
diff --git a/2_0_13/xs/maps/apache2_functions.map b/2_0_13/xs/maps/apache2_functions.map
new file mode 100644
index 0000000..1503ec7
--- /dev/null
+++ b/2_0_13/xs/maps/apache2_functions.map
@@ -0,0 +1,568 @@
+########## Apache functions ##########
+
+#keywords:
+# MODULE = the module name
+# e.g. Apache2::Connection -> Apache2/Connection.{pm,xs}
+#
+# PACKAGE = the package name functions belong to, defaults to MODULE
+# value of 'guess' indicates that package name should be
+# guessed based on first argument found that maps to a Perl class
+# fallsback on the prefix (ap_ -> Apache2, apr_ -> APR)
+#
+# PREFIX = prefix to be stripped
+# defaults to PACKAGE, converted to C name convention, e.g.
+# APR::Base64 -> apr_base64_
+# if the converted prefix does not match, defaults to ap_ or apr_
+
+#format of entries:
+# C function name | dispatch function name | argspec | Perl alias
+
+# dispatch function name defaults to C function name
+# if the dispatch name is just a prefix (mpxs_, MPXS_)
+# the C function name is appended to it
+# the return type can be specified before the C function name,
+# defaults to return_type in {Apache2,ModPerl}::FunctionTable
+
+# the argspec defaults to arguments in {Apache2,ModPerl}::FunctionTable
+# argument types can be specified to override those in the FunctionTable
+# default values can be specified, e.g. arg=default_value
+# argspec of '...' indicates passthru, calling the function with
+# (aTHX_ I32 items, SP **sp, SV **MARK)
+
+# the alias will be created in the current PACKAGE
+
+# function names that do not begin with /^\w/ are skipped
+# for details see: %ModPerl::MapUtil::disabled_map
+# in lib/ModPerl/MapUtil.pm
+
+MODULE=Apache2::RequestUtil
+ ap_get_status_line
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+ ap_register_auth_provider | mpxs_ | ...
+#_end_
+
+MODULE=Apache2::RequestUtil PACKAGE=guess
+ ap_psignature | | r, prefix
+>ap_finalize_request_protocol
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } < 2003000
+ ap_default_type
+#_end_
+ ap_get_server_name
+ ap_get_server_port
+!ap_content_type_tolower
+ ap_is_initial_req
+>ap_method_registry_init
+>ap_process_request_internal
+?ap_get_mime_headers
+>ap_rgetline_core
+?ap_get_request_note
+?ap_register_request_note
+~ap_set_content_type
+
+#MODULE=Apache2::RequestConfig
+~ap_document_root
+ ap_get_limit_req_body
+?ap_get_limit_xml_body
+>ap_core_translate
+
+>MODULE=Apache2::Core
+ ap_basic_http_header
+ ap_http_filter
+ ap_send_http_options
+ ap_send_http_trace
+ ap_response_code_string
+ ap_add_file_conf
+ ap_add_per_dir_conf
+ ap_add_per_url_conf
+ ap_limit_section
+ ap_setup_make_content_type
+
+>MODULE=Apache2::Listen
+ ap_set_listenbacklog
+ ap_set_listener
+ ap_set_send_buffer_size
+ ap_setup_listeners
+
+MODULE=Apache2::SubRequest PACKAGE=Apache2::RequestRec
+?ap_sub_req_output_filter
+>ap_set_sub_req_protocol
+-ap_finalize_sub_req_protocol
+ ap_internal_redirect | | r, new_uri
+ ap_internal_redirect_handler | | r, new_uri
+ ap_internal_fast_redirect | | r, sub_req
+ ap_sub_req_lookup_dirent | | r, finfo, subtype=AP_SUBREQ_NO_ARGS, next_filter=NULL | lookup_dirent
+
+subrequest_rec *:ap_sub_req_lookup_file | | \
+ r, new_file, next_filter=r->proto_output_filters | lookup_file
+
+subrequest_rec *:ap_sub_req_lookup_uri | | \
+ r, new_uri, next_filter=r->proto_output_filters | lookup_uri
+
+subrequest_rec *:ap_sub_req_method_uri | | \
+ r, method, new_uri, next_filter=r->proto_output_filters | lookup_method_uri
+
+PACKAGE=Apache2::SubRequest ISA=Apache2::RequestRec
+ ap_destroy_sub_req | | r | DESTROY
+ ap_run_sub_req | mpxs_ | | run
+
+MODULE=Apache2::RequestIO PACKAGE=Apache2::RequestRec
+ ap_discard_request_body
+!ap_getline
+ ap_get_client_block | mpxs_ | r, SV *:buffer, bufsiz
+ ap_setup_client_block | | r, read_policy=REQUEST_CHUNKED_ERROR
+ ap_should_client_block
+PREFIX=ap_r
+~ap_rwrite
+ ap_rprintf | mpxs_ | ...
+!ap_rputc
+~ap_rputs
+ ap_rvputs | mpxs_ | ... | puts
+-ap_vrprintf
+
+MODULE=Apache2::Response PACKAGE=guess
+ ap_make_etag | | r, force_weak=0
+ ap_set_content_length | | r, length=r->finfo.csize
+ ap_set_etag
+ ap_meets_conditions
+ ap_rationalize_mtime
+ ap_update_mtime | | r, dependency_mtime=0
+ ap_send_error_response
+~ap_send_fd
+ ap_send_mmap | | r, mm, offset, length
+ ap_set_keepalive
+-ap_set_last_modified
+ ap_custom_response
+
+MODULE=Apache2::Access PACKAGE=Apache2::RequestRec
+ ap_allow_methods | mpxs_ | ...
+ ap_allow_options
+ ap_allow_overrides
+!ap_allow_standard_methods
+ ap_get_remote_logname
+ SV *:ap_requires | mpxs_
+ ap_satisfies
+
+#MODULE=Apache2::Auth
+ mpxs_Apache2__RequestRec_auth_name | | r, name=NULL
+ mpxs_Apache2__RequestRec_auth_type | | r, type=NULL
+ ap_get_basic_auth_pw | MPXS_ | r
+ ap_note_auth_failure
+ ap_note_basic_auth_failure
+ ap_note_digest_auth_failure
+ ap_some_auth_required
+
+!MODULE=Apache2::ScriptUtil PACKAGE=guess
+ ap_add_cgi_vars
+ ap_add_common_vars
+ ap_create_environment
+ ap_find_path_info
+-ap_scan_script_header_err
+-ap_scan_script_header_err_core
+-ap_scan_script_header_err_strs
+-ap_scan_script_header_err_brigade
+
+MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerRec BOOT=1
+~ap_method_register
+ int:DEFINE_method_register | | server_rec *:s, const char *:methname
+~add_version_component
+ void:DEFINE_add_version_component | | server_rec *:s, const char *:component
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+ mpxs_Apache2__ServerRec_loglevel | | server_rec *:s, loglevel=0
+#_end_
+
+MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerUtil
+ ap_exists_config_define
+ ap_server_root_relative | | p, fname=""
+ ap_get_server_banner
+ ap_get_server_description
+ ap_get_server_version
+
+MODULE=Apache2::ServerUtil PACKAGE=guess
+ ap_error_log2stderr
+?ap_replace_stderr_log
+
+#MODULE=Apache2::ServerConfig
+#XXX: thought this might be useful
+#however it is not exported on win32
+!ap_get_local_host
+~ap_get_server_built
+~ap_server_root
+
+
+MODULE=Apache2::Connection PACKAGE=guess
+#XXX: thought this might be useful for protocol modules
+#however it is not exported on win32
+!ap_read_request
+>ap_update_vhost_given_ip
+ mpxs_Apache2__Connection_get_remote_host | | c, type=REMOTE_NAME, dir_config=NULL
+
+MODULE=Apache2::Log PACKAGE=guess
+?ap_log_assert
+~ap_log_error
+-ap_log_perror
+~ap_log_rerror
+>ap_open_stderr_log
+>ap_open_logs
+
+PACKAGE=Apache2::Log PREFIX=ap_
+ ap_log_pid
+
+MODULE=Apache2::Module
+ module *:DEFINE_top_module
+-ap_add_loaded_module
+-ap_add_module
+-ap_add_named_module
+ ap_find_linked_module
+-ap_find_module_name
+ap_remove_loaded_module
+-ap_remove_module
+>ap_single_module_configure
+>ap_setup_prelinked_modules
+>ap_show_directives
+>ap_show_modules
+>ap_register_hooks
+ mpxs_Apache2__Module_loaded
+ mpxs_Apache2__Module_add
+ #ap_get_module_config
+ mpxs_Apache2__Module_get_config | | pmodule, s, v=NULL
+ mpxs_Apache2__Module_ap_api_major_version
+ mpxs_Apache2__Module_ap_api_minor_version
+
+MODULE=Apache2::Directive
+ ap_directive_t *:DEFINE_conftree
+!ap_add_node
+!ap_build_config
+!ap_build_cont_config
+!ap_walk_config
+>ap_process_config_tree
+
+MODULE=Apache2::Filter PACKAGE=guess
+~ap_add_output_filter
+~ap_add_input_filter
+-ap_add_input_filter_handle
+-ap_get_input_filter_handle
+-ap_add_output_filter_handle
+-ap_get_output_filter_handle
+>ap_add_ouput_filters_by_type
+~ap_get_brigade
+ mpxs_Apache2__Filter_get_brigade | | \
+ f, bb, mode=AP_MODE_READBYTES, \
+ block=APR_BLOCK_READ, \
+ readbytes=8192
+~ap_pass_brigade
+ mpxs_Apache2__Filter_pass_brigade
+!ap_register_input_filter
+!ap_register_output_filter
+-ap_remove_output_filter
+-ap_remove_input_filter
+!ap_save_brigade
+ ap_filter_flush
+~ap_fflush
+ mpxs_Apache2__Filter_fflush
+-ap_fputstrs
+#int:DEFINE_ap_fputs | | \
+# ap_filter_t *:f, apr_bucket_brigade *:bb, const char *:str
+-ap_fprintf
+>ap_byterange_filter
+>ap_http_header_filter
+>ap_content_length_filter
+>ap_old_write_filter
+
+!MODULE=Apache2::Bucket
+ ap_bucket_error_create
+ ap_bucket_error_make
+
+!MODULE=Apache2::Base64
+ ap_pbase64decode
+ ap_pbase64encode
+
+!MODULE=Apache2::ConfigFile
+ ap_cfg_closefile
+ ap_cfg_getc
+ ap_cfg_getline
+ ap_pcfg_open_custom
+ ap_pcfg_openfile
+>ap_read_config
+>ap_merge_per_dir_configs
+>ap_create_conn_config
+>ap_parse_htaccess
+>ap_process_resource_config
+
+MODULE=Apache2::Command
+ command_rec *:DEFINE_next | | command_rec *:cmd
+-ap_soak_end_container
+-ap_set_int_slot
+-ap_set_file_slot
+-ap_set_flag_slot
+-ap_set_string_slot
+-ap_set_string_slot_lower
+-ap_set_deprecated
+
+MODULE=Apache2::Util
+ ap_ht_time | | p, t=TIME_NOW, fmt=DEFAULT_TIME_FORMAT, gmt=1
+!ap_rfc1413
+!ap_escape_html | | s, p
+ #escape_uri
+ ap_os_escape_path | | path, p, partial=TRUE | escape_path
+!ap_explode_recent_gmt
+!ap_explode_recent_localtime
+!ap_recent_ctime
+!ap_recent_rfc822_date
+
+MODULE=Apache2::URI PACKAGE=guess
+ ap_parse_uri
+ ap_construct_url | | r, uri=r->uri, p=r->pool
+ ap_construct_server | | r, hostname=ap_get_server_name(r), \
+ port=ap_get_server_port(r), p=r->pool
+PACKAGE=Apache2::URI
+ char *:ap_unescape_url | mpxs_ | SV *:url
+
+PACKAGE=Apache2::RequestRec
+ mpxs_Apache2__RequestRec_parsed_uri
+
+!MODULE=Apache2::StringUtil PACKAGE=guess
+ ap_count_dirs
+ ap_escape_path_segment
+ ap_escape_quotes
+ ap_escape_shell_cmd
+ ap_field_noparam
+ ap_find_last_token
+ ap_find_list_item
+ ap_find_token
+ ap_get_list_item
+ ap_size_list_item
+ ap_getparents
+ ap_get_token
+-ap_getword
+-ap_getword_conf
+-ap_getword_conf_nc
+-ap_getword_nc
+-ap_getword_nulls
+-ap_getword_nulls_nc
+-ap_getword_white
+-ap_getword_white_nc
+-ap_ind
+-ap_rind
+ ap_is_directory
+ ap_is_matchexp
+ ap_is_rdirectory
+ ap_is_url
+ ap_make_dirstr_parent
+ ap_make_dirstr_prefix
+ ap_make_full_path
+ ap_no2slash
+ ap_os_is_path_absolute
+ ap_resolve_env
+-ap_strcasecmp_match
+-ap_strcasestr
+-ap_strcmp_match
+ ap_stripprefix
+-ap_str_tolower
+
+!MODULE=Apache2::MethodList
+ ap_clear_method_list
+-ap_copy_method_list
+ ap_make_method_list
+ ap_method_in_list
+ ap_method_list_add
+ ap_method_list_do
+ ap_method_list_remove
+ ap_method_list_vdo
+ ap_method_name_of
+ ap_method_number_of
+
+!MODULE=Apache2::PipedLog
+ ap_close_piped_log
+ ap_open_piped_log
+
+!MODULE=Apache2::Scoreboard
+ ap_exists_scoreboard_image
+-ap_update_child_status
+-ap_time_process_request
+-ap_create_scoreboard
+ ap_cleanup_scoreboard
+ ap_increment_counts
+ ap_calc_scoreboard_size
+ ap_create_sb_handle
+ ap_get_scoreboard_global
+ ap_get_scoreboard_process
+ ap_get_scoreboard_worker
+>ap_init_scoreboard
+>ap_reopen_scoreboard
+ ap_update_child_status_from_indexes
+
+!MODULE=Apache2::Hooks
+ ap_location_walk
+ ap_directory_walk
+ ap_file_walk
+ ap_hook_access_checker
+ ap_hook_auth_checker
+ ap_hook_check_user_id
+ ap_hook_child_init
+>ap_hook_create_connection
+>ap_hook_get_create_connection
+ ap_hook_default_port
+ ap_hook_fixups
+ ap_hook_handler
+ ap_hook_header_parser
+ ap_hook_http_method
+ ap_hook_insert_filter
+ ap_hook_log_transaction
+ ap_hook_open_logs
+ ap_hook_optional_fn_retrieve
+ ap_hook_post_config
+ ap_hook_post_read_request
+ ap_hook_pre_config
+ ap_hook_pre_connection
+ ap_hook_process_connection
+ ap_hook_translate_name
+ ap_hook_type_checker
+!ap_hook_quick_handler
+ ap_hook_map_to_storage
+ ap_hook_create_request
+ ap_hook_error_log
+>ap_hook_pre_mpm
+-ap_hook_get_suexec_identity
+-ap_hook_get_access_checker
+-ap_hook_get_auth_checker
+-ap_hook_get_check_user_id
+-ap_hook_get_child_init
+-ap_hook_get_create_request
+-ap_hook_get_default_port
+-ap_hook_get_error_log
+-ap_hook_get_fixups
+-ap_hook_get_get_mgmt_items
+-ap_hook_get_get_suexec_identity
+-ap_hook_get_handler
+-ap_hook_get_header_parser
+-ap_hook_get_http_method
+-ap_hook_get_insert_filter
+-ap_hook_get_log_transaction
+-ap_hook_get_map_to_storage
+-ap_hook_get_mgmt_items
+-ap_hook_get_open_logs
+-ap_hook_get_optional_fn_retrieve
+-ap_hook_get_post_config
+-ap_hook_get_post_read_request
+-ap_hook_get_pre_config
+-ap_hook_get_pre_connection
+-ap_hook_get_pre_mpm
+-ap_hook_get_process_connection
+-ap_hook_get_quick_handler
+-ap_hook_get_translate_name
+-ap_hook_get_type_checker
+
+MODULE=Apache2::HookRun PACKAGE=guess
+-ap_run_get_suexec_identity
+-ap_run_optional_fn_retrieve
+>ap_run_pre_config
+>ap_run_open_logs
+>ap_run_post_config
+>ap_run_insert_filter
+>ap_run_child_init
+?ap_run_default_port
+?ap_run_http_method
+>ap_run_create_connection
+>ap_run_pre_connection
+>ap_run_process_connection
+ ap_run_post_read_request
+ ap_run_translate_name
+ ap_run_header_parser
+ ap_run_access_checker
+ ap_run_check_user_id
+ ap_run_auth_checker
+ ap_run_type_checker
+ ap_run_fixups
+ ap_run_handler
+ ap_run_log_transaction
+>ap_run_rewrite_args
+?ap_run_create_request
+>ap_run_error_log
+>ap_run_get_mgmt_items
+ ap_run_map_to_storage
+>ap_run_pre_mpm
+!ap_run_quick_handler
+ ap_invoke_handler
+ ap_die | | r, type
+
+!MODULE=Apache2::MD5
+ ap_md5
+ ap_md5_binary
+ ap_md5contextTo64
+ ap_md5digest
+
+-MODULE=Apache2::Regexp
+ ap_pregcomp
+ ap_pregfree
+ ap_pregsub
+ ap_regerror
+ ap_regexec
+
+!MODULE=Apache2::VHost
+-ap_set_name_virtual_host
+-ap_fini_vhost_config
+-ap_init_vhost_config
+ ap_matches_request_vhost
+ ap_parse_vhost_addrs
+-ap_update_vhost_from_headers
+-ap_fixup_virtual_hosts
+
+!MODULE=Apache2::HTTPCore
+>ap_process_request
+>ap_make_content_type
+>ap_core_reorder_directories
+>ap_index_of_response
+
+!MODULE=Apache2::XML
+ ap_xml_parse_input
+
+MODULE=Apache2::MPM PACKAGE=Apache2::MPM BOOT=1
+~ap_mpm_query
+~ap_show_mpm
+>ap_mpm_run
+?ap_os_create_privileged_process
+?ap_wait_or_timeout
+?ap_graceful_stop_signalled
+?ap_process_child_status
+?ap_reclaim_child_processes
+?ap_sock_disable_nagle
+?ap_gname2id
+?ap_uname2id
+?ap_lingering_close
+?ap_mpm_pod_check
+?ap_mpm_pod_close
+?ap_mpm_pod_killpg
+?ap_mpm_pod_open
+?ap_mpm_pod_signal
+?ap_mpm_set_accept_lock_mech
+?ap_mpm_set_coredumpdir
+?ap_mpm_set_lockfile
+?ap_mpm_set_max_requests
+?ap_mpm_set_pidfile
+?ap_mpm_set_scoreboard
+?ap_listen_pre_config
+
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+MODULE=Apache2::Provider
+ ap_register_provider
+#_end_
diff --git a/2_0_13/xs/maps/apache2_structures.map b/2_0_13/xs/maps/apache2_structures.map
new file mode 100644
index 0000000..c9ff850
--- /dev/null
+++ b/2_0_13/xs/maps/apache2_structures.map
@@ -0,0 +1,336 @@
+########## Apache structures ##########
+
+# for mapping see %ModPerl::MapUtil::disabled_map in
+# lib/ModPerl/MapUtil.pm
+# the mapping happens in lib/ModPerl/StructureMap.pm: sub parse
+# '<' => 'auto-generated but gives only a read-only access'
+# '&' => 'RDWR accessor to a char* field, supporting undef arg'
+# '$' => 'RONLY accessor, with WRITE accessor before child_init'
+# '%' => like $, but makes sure that for the write accessor the
+# original perl scalar can change or go away w/o affecting
+# the object
+# my %disabled_map = (
+# '!' => 'disabled or not yet implemented',
+# '~' => 'implemented but not auto-generated',
+# '-' => 'likely never be available to Perl',
+# '>' => '"private" to apache',
+# '?' => 'unclassified',
+# );
+
+IGNORE: ap_LINK_ ap_filter_func ap_bucket_error ap_listen_rec core_net_rec
+
+<request_rec>
+< pool
+< connection
+< server
+< next
+< prev
+< main
+ the_request
+ assbackwards
+~ proxyreq
+< header_only
+< protocol
+< proto_num
+ hostname
+< request_time
+ status_line
+ status
+ method
+ method_number
+ allowed
+ allowed_xmethods
+ allowed_methods
+> sent_bodyct
+ bytes_sent
+ mtime
+> chunked
+> range
+> clength
+- remaining
+> read_length
+> read_body
+> read_chunked
+> expecting_100
+ headers_in
+ headers_out
+ err_headers_out
+~ subprocess_env
+ notes
+~ content_type
+~ handler
+ content_encoding
+~ content_languages
+> vlist_validator
+ user
+ ap_auth_type
+~ no_cache
+ no_local_copy
+< unparsed_uri
+ uri
+ filename
+- canonical_filename
+ path_info
+ args
+~ finfo
+~ parsed_uri
+ used_path_info
+< per_dir_config
+< request_config
+! htaccess
+ output_filters
+ input_filters
+ proto_output_filters
+ proto_input_filters
+? eos_sent
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+< useragent_addr
+ useragent_ip
+#_end_
+</request_rec>
+
+<server_rec>
+< process
+< next
+- defn_name
+- defn_line_number
+% server_admin
+% server_hostname
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+% server_scheme
+#_end_
+$ port
+% error_fname
+$ error_log
+$ loglevel
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+~ is_virtual
+#_else_
+< is_virtual
+#_end_
+< module_config
+< lookup_defaults
+< addrs
+$ timeout
+$ keep_alive_timeout
+$ keep_alive_max
+$ keep_alive
+% path
+- pathlen
+% names
+% wild_names
+$ limit_req_line
+$ limit_req_fieldsize
+$ limit_req_fields
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+ context
+#_end_
+</server_rec>
+
+<conn_rec>
+< pool
+< base_server
+> vhost_lookup_data
+< local_addr
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+< client_addr
+ client_ip
+#_end_
+< local_ip
+< local_host
+< remote_addr
+ remote_ip
+< remote_host
+- remote_logname
+< aborted
+ keepalive
+? double_reverse
+ keepalives
+< id
+< conn_config
+ notes
+ input_filters
+ output_filters
+< sbh
+< bucket_alloc
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+< log
+< log_id
+#_end_
+</conn_rec>
+
+!<server_addr_rec>
+ next
+ host_addr
+ host_port
+ virthost
+</server_addr_rec>
+
+<module>
+~ version
+~ minor_version
+< module_index
+< name
+! dynamic_load_handle
+< next
+> magic
+- rewrite_args
+> create_dir_config
+> merge_dir_config
+> create_server_config
+> merge_server_config
+< cmds
+> register_hooks
+</module>
+
+<process_rec>
+< pool
+< pconf
+- argc
+! argv
+< short_name
+</process_rec>
+
+<command_rec>
+< name
+! func
+! cmd_data
+< req_override
+< args_how
+< errmsg
+</command_rec>
+
+<ap_filter_rec_t>
+< name
+- filter_func
+! ftype
+- next
+</ap_filter_rec_t>
+
+<ap_filter_t>
+< frec
+~ ctx
+ next
+ r
+ c
+</ap_filter_t>
+
+!<ap_method_list_t>
+ method_mask
+ method_list
+</ap_method_list_t>
+
+<ap_directive_t>
+< directive
+< args
+< next
+< first_child
+< parent
+! data
+< filename
+< line_num
+</ap_directive_t>
+
+!<ap_configfile_t>
+ getch
+ getstr
+ close
+ param
+ name
+ line_number
+</ap_configfile_t>
+
+!<ap_unix_identity_t>
+ uid
+ gid
+ userdir
+</ap_unix_identity_t>
+
+!<unixd_config_rec>
+ user_name
+ user_id
+ group_id
+ suexec_enabled
+</unixd_config_rec>
+
+!<htaccess_result>
+ dir
+ override
+ htaccess
+ next
+</htaccess_result>
+
+!<piped_log>
+ p
+ fds
+ program
+ pid
+</piped_log>
+
+<cmd_parms>
+- info
+< override
+! limited
+! limited_xmethods
+! xlimited
+! config_file
+< directive
+< pool
+< temp_pool
+< server
+< path
+< cmd
+< context
+! err_directive
+- override_opts
+</cmd_parms>
+
+!<ap_mgmt_item_t>
+ description
+ name
+ vtype
+ v
+</ap_mgmt_item_t>
+
+!<ap_mgmt_value>
+ s_value
+ i_value
+ h_value
+</ap_mgmt_value>
+
+!<ap_pod_t>
+ pod_in
+ pod_out
+ p
+ sa
+</ap_pod_t>
diff --git a/2_0_13/xs/maps/apache2_types.map b/2_0_13/xs/maps/apache2_types.map
new file mode 100644
index 0000000..156a919
--- /dev/null
+++ b/2_0_13/xs/maps/apache2_types.map
@@ -0,0 +1,93 @@
+########## Apache types ##########
+
+struct server_rec | Apache2::ServerRec
+struct server_addr_rec | Apache2::ServerAddr
+struct conn_rec | Apache2::Connection
+struct request_rec | Apache2::RequestRec
+struct subrequest_rec | Apache2::SubRequest
+struct process_rec | Apache2::Process
+struct ap_method_list_t | Apache2::MethodList
+struct piped_log | Apache2::PipedLog
+
+struct module | Apache2::Module
+struct module_struct | Apache2::Module
+
+ap_conn_keepalive_e | IV
+
+#config stuff
+struct command_rec | Apache2::Command
+enum cmd_how | IV
+cmd_func | UNDEFINED
+struct cmd_parms | Apache2::CmdParms
+struct ap_configfile_t | Apache2::ConfigFile
+struct htaccess_result | UNDEFINED
+struct ap_directive_t | Apache2::Directive
+struct ap_conf_vector_t | Apache2::ConfVector
+
+#system-ish stuff
+ap_mgmt_type_e | IV
+ap_mgmt_value | UNDEFINED
+ap_scoreboard_e | IV
+struct process_score | UNDEFINED
+struct worker_score | UNDEFINED
+struct ap_pod_t | UNDEFINED
+ap_unix_identity_t | UNDEFINED
+
+#filters
+struct ap_filter_t | Apache2::Filter
+struct ap_filter_rec_t | Apache2::FilterRec
+ap_filter_type | Apache2::FilterType
+ap_filter_func | UNDEFINED
+ap_out_filter_func | UNDEFINED
+ap_in_filter_func | UNDEFINED
+ap_input_mode_t | IV
+
+########## Standard types ##########
+
+int | IV
+int * | PTR
+unsigned int | UV
+signed int | IV
+long | IV
+long int | IV
+unsigned long | UV
+unsigned | UV
+double | NV
+
+char * | PV
+const char * | PV
+const char ** | UNDEFINED
+char const * | PV
+unsigned char * | PV
+const unsigned char * | PV
+char ** | UNDEFINED
+char *** | UNDEFINED
+const char * const * | UNDEFINED
+
+char | CHAR
+const char | CHAR
+const unsigned char | U_CHAR
+unsigned char | U_CHAR
+
+void * | PTR
+void ** | UNDEFINED
+const void * | PTR
+const void ** | UNDEFINED
+void | VOID
+
+... | UNDEFINED #varargs
+va_list | UNDEFINED
+
+########## Misc types ##########
+
+time_t | NV
+uid_t | IV
+gid_t | IV
+pid_t | IV
+size_t | IV
+size_t * | UNDEFINED
+
+struct regex_t
+regmatch_t
+struct pthread_mutex_t
+struct iovec | NOTIMPL
diff --git a/2_0_13/xs/maps/apr_functions.map b/2_0_13/xs/maps/apr_functions.map
new file mode 100644
index 0000000..b4f6182
--- /dev/null
+++ b/2_0_13/xs/maps/apr_functions.map
@@ -0,0 +1,664 @@
+########## APR Functions ##########
+
+# for mapping see %ModPerl::MapUtil::disabled_map in
+# lib/ModPerl/MapUtil.pm
+
+!MODULE=APR::Poll
+ apr_poll_socket_add
+ apr_poll_socket_clear
+ apr_poll_data_get
+ apr_poll_revents_get
+ apr_poll_socket_mask
+ apr_poll
+ apr_poll_socket_remove
+ apr_poll_data_set
+ apr_poll_setup
+
+!MODULE=APR::Time
+-apr_ctime
+ apr_implode_time
+-apr_time_now
+-apr_sleep
+ apr_rfc822_date
+ apr_strftime
+ apr_time_exp_gmt_get
+ apr_time_ansi_put
+ apr_time_exp_get
+ apr_time_exp_gmt
+ apr_time_exp_lt
+ apr_time_exp_tz
+
+MODULE=APR::Date
+-apr_date_checkmask
+ apr_date_parse_http
+ apr_date_parse_rfc
+
+!MODULE=APR::Array
+ apr_array_append
+ apr_array_cat
+ apr_array_pstrcat
+ apr_array_copy
+ apr_array_copy_hdr
+ apr_array_make
+ apr_array_push
+
+MODULE=APR::Socket
+ apr_socket_bind
+!apr_socket_accept
+ apr_socket_listen
+ apr_socket_connect
+~apr_socket_recv
+ mpxs_APR__Socket_recv
+ apr_socket_recvfrom
+ apr_socket_send | mpxs_ | sock, SV *:buf, SV *:len=(SV *)NULL
+ apr_socket_sendto
+!apr_socket_shutdown
+-apr_socket_inherit_set
+-apr_socket_inherit_unset
+#_if_ $^O !~ /mswin/i
+ mpxs_APR__Socket_fileno | | apr_socket_t *:socket
+#_end_
+
+MODULE=APR::Socket
+ apr_socket_close
+!apr_socket_create
+!apr_socket_addr_get
+!apr_socket_data_get
+!apr_socket_data_set
+~apr_socket_opt_get
+ mpxs_APR__Socket_opt_get
+~apr_socket_opt_set
+ mpxs_APR__Socket_opt_set
+ apr_socket_timeout_get | mpxs_ | ...
+~apr_socket_timeout_set
+ mpxs_APR__Socket_timeout_set
+-apr_socket_sendfile
+-apr_socket_sendv
+!apr_socket_from_file
+ mpxs_APR__Socket_poll
+
+MODULE=APR::SockAddr
+!apr_sockaddr_info_get
+ char *:apr_sockaddr_ip_get | mpxs_ | sockaddr
+ apr_sockaddr_equal
+
+MODULE=APR::Brigade
+ SV *:apr_brigade_create | mpxs_ | SV *:CLASS, SV *:p_sv, list | new
+~apr_brigade_destroy
+ mpxs_APR__Brigade_destroy
+!apr_brigade_partition
+!apr_brigade_printf
+-apr_brigade_putstrs
+ apr_brigade_split
+-apr_brigade_to_iovec
+-apr_brigade_vprintf
+-apr_brigade_vputstrs
+~apr_brigade_length
+!apr_brigade_write
+!apr_brigade_puts
+-apr_brigade_putc
+~ apr_brigade_cleanup
+ mpxs_APR__Brigade_cleanup
+~apr_brigade_flatten
+~apr_brigade_pflatten
+?apr_brigade_split_line
+ mpxs_APR__Brigade_first #APR_BRIGADE_FIRST
+ mpxs_APR__Brigade_last #APR_BRIGADE_LAST
+ mpxs_APR__Brigade_prev #APR_BUCKET_PREV
+ mpxs_APR__Brigade_next #APR_BUCKET_NEXT
+ mpxs_APR__Brigade_insert_tail #APR_BRIGADE_INSERT_TAIL
+ mpxs_APR__Brigade_insert_head #APR_BRIGADE_INSERT_HEAD
+ mpxs_APR__Brigade_concat #APR_BRIGADE_CONCAT
+ mpxs_APR__Brigade_is_empty #APR_BRIGADE_EMPTY
+ mpxs_APR__Brigade_length | | bb, read_all=1
+ mpxs_APR__Brigade_flatten | | ...
+ mpxs_APR__Brigade_pool
+
+MODULE=APR::Bucket
+ mpxs_APR__Bucket_is_flush #APR_BUCKET_IS_FLUSH
+ mpxs_APR__Bucket_is_eos #APR_BUCKET_IS_EOS
+ mpxs_APR__Bucket_insert_after #APR_BUCKET_INSERT_AFTER
+ mpxs_APR__Bucket_insert_before #APR_BUCKET_INSERT_AFTER
+ mpxs_APR__Bucket_remove #APR_BUCKET_REMOVE
+ #apr_bucket_read
+ mpxs_APR__Bucket_read | | bucket, buffer, block=APR_BLOCK_READ
+ #modperl_bucket_sv_create
+ mpxs_APR__Bucket_new | | classname, list, sv, offset=0, len=0
+ void:DEFINE_destroy | | apr_bucket:bucket
+ void:DEFINE_delete | | apr_bucket:bucket
+~apr_bucket_setaside
+ mpxs_APR__Bucket_setaside
+>apr_bucket_free
+!apr_bucket_copy_notimpl
+!apr_bucket_shared_copy
+ apr_bucket_eos_create
+!apr_bucket_file_create
+!apr_bucket_file_enable_mmap
+ apr_bucket_flush_create
+!apr_bucket_heap_create
+!apr_bucket_immortal_create
+!apr_bucket_mmap_create
+!apr_bucket_pipe_create
+!apr_bucket_pool_create
+!apr_bucket_socket_create
+!apr_bucket_transient_create
+!apr_bucket_shared_destroy
+!apr_bucket_eos_make
+!apr_bucket_file_make
+!apr_bucket_flush_make
+!apr_bucket_heap_make
+!apr_bucket_immortal_make
+!apr_bucket_mmap_make
+!apr_bucket_pipe_make
+!apr_bucket_pool_make
+!apr_bucket_shared_make
+!apr_bucket_socket_make
+!apr_bucket_transient_make
+!apr_bucket_setaside_notimpl
+!apr_bucket_split_notimpl
+!apr_bucket_shared_split
+!apr_bucket_simple_split
+!apr_bucket_simple_copy
+!apr_bucket_destroy_noop
+!apr_bucket_setaside_noop
+
+MODULE=APR::BucketAlloc
+>apr_bucket_alloc
+~apr_bucket_alloc_create
+ mpxs_APR__BucketAlloc_new
+ void:DEFINE_destroy | | apr_bucket_alloc_t *:ba
+
+MODULE=APR::Pool
+-apr_pool_num_bytes | | p, recurse=0 #only available with -DAPR_POOL_DEBUG
+ apr_pool_cleanup_for_exec
+~apr_pool_clear
+mpxs_APR__Pool_clear
+>apr_pool_clear_debug
+~apr_pool_destroy
+ DEFINE_destroy | mpxs_apr_pool_DESTROY | SV *:obj
+ DEFINE_DESTROY | mpxs_apr_pool_DESTROY | SV *:obj
+>apr_pool_destroy_debug
+ SV *:DEFINE_new | mpxs_apr_pool_create | SV *:parent_pool_obj
+-apr_pool_create_ex
+>apr_pool_create_ex_debug
+!apr_pool_userdata_get
+!apr_pool_userdata_set
+-apr_pool_userdata_setn
+!apr_pool_cleanup_kill
+!apr_pool_cleanup_run
+-apr_pool_cleanup_null
+ apr_pool_cleanup_register | mpxs_ | p, SV *:cv, SV *:arg=(SV *)NULL
+!apr_pool_note_subprocess
+-apr_palloc
+>apr_palloc_debug
+>apr_pcalloc_debug
+-apr_pcalloc
+-apr_pmemdup
+!apr_pool_child_cleanup_set
+!apr_pool_abort_get
+ SV *:apr_pool_parent_get | mpxs_
+ apr_pool_is_ancestor
+-apr_pool_abort_set
+>apr_pool_initialize
+>apr_pool_terminate
+ apr_pool_tag
+
+-MODULE=APR::Allocator
+ apr_allocator_alloc
+ apr_allocator_create
+ apr_allocator_destroy
+ apr_allocator_free
+ apr_allocator_mutex_get
+ apr_allocator_owner_get
+ apr_allocator_mutex_set
+ apr_allocator_owner_set
+
+-MODULE=APR::Atomic
+ apr_atomic_add
+ apr_atomic_cas
+ apr_atomic_dec
+ apr_atomic_inc
+ apr_atomic_init
+ apr_atomic_set
+
+!MODULE=APR::GlobalMutex
+ apr_global_mutex_child_init
+ apr_global_mutex_create
+ apr_global_mutex_destroy
+ apr_global_mutex_lock
+ apr_global_mutex_pool_get
+ apr_global_mutex_trylock
+ apr_global_mutex_unlock
+
+MODULE=APR::ThreadMutex PREFIX=apr_thread_mutex_
+ SV *:apr_thread_mutex_create | mpxs_ | \
+ SV *:classname, SV *:p_sv, flags=APR_THREAD_MUTEX_DEFAULT | new
+ void:apr_thread_mutex_destroy | | | apr_thread_mutex_DESTROY
+ apr_thread_mutex_lock
+ apr_thread_mutex_trylock
+ apr_thread_mutex_unlock
+ apr_thread_mutex_pool_get
+
+!MODULE=APR::ProcMutex
+ apr_proc_mutex_child_init
+ apr_proc_mutex_create
+ apr_proc_mutex_destroy
+ apr_proc_mutex_lock
+ apr_proc_mutex_pool_get
+ apr_proc_mutex_trylock
+ apr_proc_mutex_unlock
+
+MODULE=APR::Table
+ apr_table_clear
+~apr_table_copy
+ mpxs_APR__Table_copy
+~apr_table_make
+ mpxs_APR__Table_make
+ apr_table_overlap
+~apr_table_overlay
+ mpxs_APR__Table_overlay
+ apr_table_compress
+ apr_table_add
+-apr_table_addn
+ apr_table_do | mpxs_ | ...
+ apr_table_get | MPXS_ | ...
+ apr_table_merge
+-apr_table_mergen
+ apr_table_set
+-apr_table_setn
+ apr_table_unset
+-apr_table_vdo
+ void:DEFINE_STORE | | apr_table_t *:t, const char *:key, const char *:value
+ void:DEFINE_DELETE | | apr_table_t *:t, const char *:key
+ void:DEFINE_CLEAR | | apr_table_t *:t
+ const char *:DEFINE_FIRSTKEY | mpxs_APR__Table_NEXTKEY | SV *:tsv, SV *:key=(SV *)NULL
+ mpxs_APR__Table_NEXTKEY | | SV *:tsv, SV *:key=&PL_sv_undef
+ mpxs_APR__Table_FETCH
+ mpxs_APR__Table_EXISTS
+
+!MODULE=APR::File
+-apr_file_append
+-apr_file_attrs_set
+-apr_file_copy
+-apr_file_dup2
+ apr_file_mktemp
+-apr_file_open
+-apr_file_close
+-apr_file_namedpipe_create
+ apr_file_pipe_create
+-apr_file_dup
+-apr_file_flush
+-apr_file_eof
+-apr_file_gets
+-apr_file_printf
+-apr_file_write_full
+-apr_file_read_full
+-apr_file_getc
+-apr_file_ungetc
+-apr_file_putc
+-apr_file_puts
+-apr_file_read
+-apr_file_write
+-apr_file_writev
+-apr_file_seek
+ apr_file_data_get
+ apr_file_info_get
+ apr_file_name_get
+ apr_file_pool_get
+ apr_file_pipe_timeout_get
+ apr_file_pipe_timeout_set
+ apr_file_lock
+ apr_file_unlock
+ apr_file_open_stderr
+ apr_file_open_stdout
+-apr_file_remove
+-apr_file_rename
+ apr_file_data_set
+ apr_file_perms_set
+-apr_file_flags_get
+-apr_file_open_stdin
+-apr_file_set_inherit
+-apr_file_unset_inherit
+-apr_file_trunc
+ apr_filepath_get
+ apr_filepath_merge
+ apr_filepath_root
+ apr_filepath_set
+
+MODULE=APR::Finfo
+-apr_lstat
+~apr_stat
+ mpxs_APR__Finfo_stat
+
+!MODULE=APR::String
+ apr_collapse_spaces
+-apr_cpystrn
+ apr_fnmatch
+ apr_fnmatch_test
+-apr_psprintf
+-apr_pstrcat
+-apr_pstrcatv
+-apr_pstrdup
+-apr_pstrndup
+-apr_pstrmemdup
+-apr_pvsprintf
+ apr_strnatcasecmp
+ apr_strnatcmp
+-apr_tokenize_to_argv
+-apr_strtok
+-apr_itoa
+-apr_ltoa
+-apr_off_t_toa
+
+MODULE=APR::String
+ SV *:apr_strfsize | mpxs_APR__String_strfsize | size | format_size
+
+!MODULE=APR::StrMatch
+ apr_strmatch_precompile
+
+!MODULE=APR::ProcAttr
+ apr_procattr_create
+ apr_procattr_child_err_set
+ apr_procattr_child_in_set
+ apr_procattr_child_out_set
+ apr_procattr_cmdtype_set
+ apr_procattr_detach_set
+ apr_procattr_dir_set
+ apr_procattr_io_set
+ apr_procattr_limit_set
+
+!MODULE=APR::Proc
+ apr_proc_create
+ apr_proc_fork
+ apr_proc_kill
+ apr_proc_wait
+ apr_proc_detach
+-apr_proc_other_child_read
+-apr_proc_other_child_register
+-apr_proc_other_child_unregister
+-apr_proc_other_child_check
+-apr_proc_wait_all_procs
+
+-MODULE=APR::Thread
+ apr_thread_create
+ apr_thread_data_get
+ apr_thread_data_set
+ apr_thread_detach
+ apr_thread_exit
+ apr_thread_join
+ apr_thread_once
+ apr_thread_once_init
+ apr_thread_pool_get
+ apr_thread_yield
+
+-MODULE=APR::ThreadCond
+ apr_thread_cond_broadcast
+ apr_thread_cond_create
+ apr_thread_cond_destroy
+ apr_thread_cond_signal
+ apr_thread_cond_wait
+ apr_thread_cond_pool_get
+ apr_thread_cond_timedwait
+
+MODULE=APR::ThreadRWLock PREFIX=apr_thread_rwlock_
+ SV *:apr_thread_rwlock_create | mpxs_ | SV *:classname, SV *:p_sv | new
+ void:apr_thread_rwlock_destroy | | | apr_thread_rwlock_DESTROY
+ apr_thread_rwlock_rdlock
+ apr_thread_rwlock_tryrdlock
+ apr_thread_rwlock_trywrlock
+ apr_thread_rwlock_unlock
+ apr_thread_rwlock_wrlock
+ apr_thread_rwlock_pool_get
+
+-MODULE=APR::ThreadKey
+ apr_threadkey_data_get
+ apr_threadkey_data_set
+ apr_threadkey_private_get
+ apr_threadkey_private_set
+ apr_threadkey_private_create
+ apr_threadkey_private_delete
+
+-MODULE=APR::ThreadAttr
+ apr_threadattr_create
+ apr_threadattr_detach_set
+ apr_threadattr_detach_get
+
+!MODULE=APR::Version
+ apr_version
+ apr_version_string
+
+-MODULE=APR::DBM
+ apr_dbm_close
+ apr_dbm_delete
+ apr_dbm_exists
+ apr_dbm_fetch
+ apr_dbm_firstkey
+ apr_dbm_freedatum
+ apr_dbm_geterror
+ apr_dbm_get_usednames
+ apr_dbm_get_usednames_ex
+ apr_dbm_nextkey
+ apr_dbm_open
+ apr_dbm_open_ex
+ apr_dbm_store
+
+-MODULE=APR::SDBM
+ apr_sdbm_close
+ apr_sdbm_delete
+ apr_sdbm_fetch
+ apr_sdbm_firstkey
+ apr_sdbm_lock
+ apr_sdbm_nextkey
+ apr_sdbm_open
+ apr_sdbm_rdonly
+ apr_sdbm_store
+ apr_sdbm_unlock
+
+-MODULE=APR::Dir
+ apr_dir_close
+ apr_dir_open
+ apr_dir_read
+ apr_dir_rewind
+ apr_dir_make
+ apr_dir_remove
+
+!MODULE=APR::DSO
+ apr_dso_error
+ apr_dso_load
+ apr_dso_sym
+ apr_dso_unload
+
+MODULE=APR::Util
+ apr_filepath_name_get
+ apr_password_get
+ int:apr_password_validate | mpxs_
+-apr_snprintf
+-apr_vformatter
+-apr_vsnprintf
+# only available if APR_HAS_RANDOM
+-apr_generate_random_bytes
+
+MODULE=APR::Error
+~apr_strerror
+ char *:DEFINE_strerror | | apr_status_t:rc
+
+!MODULE=APR::General
+-apr_app_initialize
+-apr_initialize
+-apr_terminate
+-apr_terminate2
+
+MODULE=APR::Signal
+-apr_signal
+#not available on all platforms
+!apr_signal_description_get
+-apr_signal_init
+-apr_setup_signal_thread
+!apr_signal_thread
+
+MODULE=APR::UUID
+ apr_uuid_format | MPXS_ | uuid
+ apr_uuid_t *:apr_uuid_get | mpxs_ | SV *:CLASS | new
+ apr_uuid_t *:apr_uuid_parse | mpxs_ | SV *:CLASS,char *:buf | parse
+ apr_uuid_DESTROY | | uuid
+
+!MODULE=APR::Hook
+ apr_hook_deregister_all
+ apr_hook_sort_register
+-apr_register_optional_fn
+ apr_hook_debug_show
+ apr_hook_sort_all
+ apr_optional_hook_add
+ apr_optional_hook_get
+
+!MODULE=APR::User
+ apr_gid_name_get
+ apr_uid_homepath_get
+ apr_uid_name_get
+ apr_uid_get
+ apr_gid_get
+ apr_uid_current
+
+!MODULE=APR::NetLib
+-apr_gethostname
+!apr_getnameinfo
+-apr_getservbyname
+!apr_parse_addr_port
+
+MODULE=APR::IpSubnet
+ SV *:apr_ipsubnet_create | mpxs_ | \
+ SV *:CLASS, SV *:p_sv, ipstr, mask_or_numbits=NULL | new
+ apr_ipsubnet_test
+
+!MODULE=APR::Getopt
+ apr_getopt
+ apr_getopt_long
+ apr_getopt_init
+
+!MODULE=APR::Shm
+ apr_shm_create
+ apr_shm_destroy
+ apr_shm_attach
+ apr_shm_detach
+ apr_shm_baseaddr_get
+ apr_shm_size_get
+ apr_shm_pool_get
+
+!MODULE=APR::Hash
+ apr_hash_copy
+ apr_hash_count
+ apr_hash_first
+ apr_hash_get
+ apr_hash_merge
+ apr_hash_next
+ apr_hash_set
+ apr_hash_this
+ apr_hash_make
+ apr_hash_overlay
+ apr_hash_pool_get
+
+!MODULE=APR::MD5
+ apr_md5
+ apr_md5_encode
+ apr_md5_final
+ apr_md5_init
+ apr_md5_set_xlate
+ apr_md5_update
+
+!MODULE=APR::MD4
+ apr_md4
+ apr_md4_final
+ apr_md4_init
+ apr_md4_set_xlate
+ apr_md4_update
+
+!MODULE=APR::SHA1
+ apr_sha1_base64
+ apr_sha1_final
+ apr_sha1_init
+ apr_sha1_update
+ apr_sha1_update_binary
+
+MODULE=APR::Base64
+ apr_base64_decode | MPXS_ | coded_src
+ apr_base64_encode | MPXS_ | plain_src
+ int:DEFINE_encode_len | | int:len
+-apr_base64_decode_len
+-apr_base64_encode_binary
+-apr_base64_decode_binary
+
+MODULE=APR::URI
+!apr_uri_parse_hostinfo
+ SV *:apr_uri_parse | mpxs_ | SV *:classname, SV *:p_sv, uri | parse
+ apr_uri_unparse | mpxs_ | \
+ uptr, flags=APR_URI_UNP_OMITPASSWORD | unparse
+ #special case to set both uri->port and uri->port_str
+ mpxs_APR__URI_port | | uri, portsv=(SV *)NULL
+ mpxs_APR__URI_rpath
+ apr_uri_port_of_scheme
+
+!MODULE=Apache2::XML
+ apr_text_append
+ apr_xml_parser_create
+ apr_xml_parser_feed
+ apr_xml_parser_done
+ apr_xml_parser_geterror
+ apr_xml_to_text
+ apr_xml_empty_elem
+ apr_xml_quote_string
+ apr_xml_quote_elem
+ apr_xml_insert_uri
+ apr_xml_parse_file
+
+!MODULE=APR::Mmap
+ apr_mmap_create
+ apr_mmap_delete
+ apr_mmap_offset
+ apr_mmap_dup
+
+!MODULE=APR::Xlate
+ apr_xlate_close
+ apr_xlate_conv_buffer
+ apr_xlate_conv_byte
+ apr_xlate_get_sb
+ apr_xlate_open
+
+MODULE=APR::OS
+ mpxs_APR__OS_current_thread_id
+-apr_os_dir_get
+-apr_os_exp_time_get
+-apr_os_file_get
+-apr_os_imp_time_get
+#_if_ $^O !~ /mswin/i
+~apr_os_sock_get
+#_else_
+-apr_os_sock_get
+#_end_
+-apr_os_thread_get
+-apr_os_threadkey_get
+-apr_os_sock_make
+-apr_os_dir_put
+-apr_os_exp_time_put
+-apr_os_file_put
+-apr_os_imp_time_put
+-apr_os_sock_put
+-apr_os_thread_put
+-apr_os_threadkey_put
+-apr_os_dso_handle_get
+-apr_os_dso_handle_put
+~apr_os_thread_current
+-apr_os_thread_equal
+-apr_os_global_mutex_get
+-apr_os_proc_mutex_get
+-apr_os_proc_mutex_put
+-apr_os_shm_get
+-apr_os_shm_put
+
+MODULE=APR::Status PREFIX=mpxs_APR__STATUS_
+ int:DEFINE_is_EAGAIN | | apr_status_t:rc
+ int:DEFINE_is_EACCES | | apr_status_t:rc
+ int:DEFINE_is_ENOENT | | apr_status_t:rc
+ int:DEFINE_is_EOF | | apr_status_t:rc
+ int:DEFINE_is_ECONNABORTED | | apr_status_t:rc
+ int:DEFINE_is_ECONNRESET | | apr_status_t:rc
+ int:DEFINE_is_TIMEUP | | apr_status_t:rc
diff --git a/2_0_13/xs/maps/apr_structures.map b/2_0_13/xs/maps/apr_structures.map
new file mode 100644
index 0000000..970ce68
--- /dev/null
+++ b/2_0_13/xs/maps/apr_structures.map
@@ -0,0 +1,189 @@
+########## APR structures ##########
+
+# for mapping see %ModPerl::MapUtil::disabled_map in
+# lib/ModPerl/MapUtil.pm
+
+IGNORE: apr_pool_t apr_os_ apr_vformatter_buff_t apr_pool_t \
+apr_table_t apr_in_addr_t apr_bucket_ apr_md5_ctx_t apr_sha1_ctx_t \
+apr_md4_ctx_t apr_sdbm_datum_t apr_memnode_t \
+apr_uuid_t apr_datum_t apr_mmap_t apr_hdtr_t apr_ipsubnet_t \
+apr_strmatch_pattern apr_version_t
+
+#buckets
+
+<apr_bucket_type_t>
+< name
+- num_func
+- destroy
+- read
+- setaside
+- split
+- copy
+</apr_bucket_type_t>
+
+<apr_bucket>
+> link
+< type
+< length
+< start
+< data
+> free
+> list
+</apr_bucket>
+
+<apr_bucket_brigade>
+~ pool
+> list
+< bucket_alloc
+</apr_bucket_brigade>
+
+<apr_finfo_t>
+- pool
+< valid
+< protection
+< filetype
+< user
+< group
+< inode
+< device
+< nlink
+< size
+< csize
+< atime
+< mtime
+< ctime
+< fname
+< name
+- filehand
+</apr_finfo_t>
+
+<apr_sockaddr_t>
+- pool
+- hostname
+- servname
+< port
+- sa
+- salen
+- ipaddr_len
+- addr_str_len
+- ipaddr_ptr
+- next
+- family
+</apr_sockaddr_t>
+
+!<apr_proc_t>
+ pid
+ in
+ out
+ err
+</apr_proc_t>
+
+!<apr_time_exp_t>
+ tm_usec
+ tm_sec
+ tm_min
+ tm_hour
+ tm_mday
+ tm_mon
+ tm_year
+ tm_wday
+ tm_yday
+ tm_isdst
+ tm_gmtoff
+</apr_time_exp_t>
+
+#generic data structures
+
+!<apr_array_header_t>
+> pool
+> elt_size
+ nelts
+> nalloc
+ elts
+</apr_array_header_t>
+
+!<apr_table_entry_t>
+ key
+ val
+> key_checksum
+</apr_table_entry_t>
+
+#getopt
+
+!<apr_getopt_t>
+- cont
+- errfn
+ errarg
+ ind
+- opt
+- reset
+ argc
+ argv
+- place
+- interleave
+- skip_start
+- skip_end
+</apr_getopt_t>
+
+!<apr_getopt_option_t>
+ name
+- optch
+- has_arg
+ description
+</apr_getopt_option_t>
+
+#XML
+
+!<apr_xml_elem>
+ name
+ ns
+ lang
+ first_cdata
+ following_cdata
+ parent
+ next
+ first_child
+ attr
+ last_child
+ ns_scope
+ priv
+</apr_xml_elem>
+
+<apr_xml_doc>
+ root
+ namespaces
+</apr_xml_doc>
+
+<apr_text_header>
+ first
+ last
+</apr_text_header>
+
+<apr_xml_attr>
+ name
+ ns
+ value
+ next
+</apr_xml_attr>
+
+<apr_text>
+ text
+ next
+</apr_text>
+
+<apr_uri_t>
+& scheme
+ hostinfo
+& user
+& password
+& hostname
+- port_str
+& path
+& query
+& fragment
+ hostent
+~ port
+- is_initialized
+- dns_looked_up
+- dns_resolved
+</apr_uri_t>
diff --git a/2_0_13/xs/maps/apr_types.map b/2_0_13/xs/maps/apr_types.map
new file mode 100644
index 0000000..0508609
--- /dev/null
+++ b/2_0_13/xs/maps/apr_types.map
@@ -0,0 +1,149 @@
+########## APR types ##########
+
+struct apr_xlate_t | UNDEFINED
+struct apr_pool_t | APR::Pool
+apr_abortfunc_t | UNDEFINED
+
+#socket stuff
+struct apr_sockaddr_t | APR::SockAddr
+apr_os_sock_info_t | APR::SockInfo
+struct apr_os_sock_t | UNDEFINED
+struct apr_in_addr_t | APR::InAddr
+apr_port_t | IV
+struct apr_socket_t | APR::Socket
+struct sockaddr | UNDEFINED
+struct hostent | UNDEFINED
+apr_shutdown_how_e | UNDEFINED
+apr_interface_e | UNDEFINED
+
+struct apr_ipsubnet_t | APR::IpSubnet
+
+#bucket stuff
+struct apr_bucket | APR::Bucket
+struct apr_bucket_brigade | APR::Brigade
+struct apr_bucket_alloc_t | APR::BucketAlloc
+apr_brigade_flush | UNDEFINED
+struct apr_bucket_type_t | APR::BucketType
+apr_read_type_e | IV
+apr_bucket_file | UNDEFINED
+apr_bucket_pool | UNDEFINED
+apr_bucket_heap | UNDEFINED
+apr_bucket_mmap | UNDEFINED
+apr_bucket_refcount | UNDEFINED
+apr_bucket_list | UNDEFINED
+#apr_bucket_simple | UNDEFINED
+#apr_bucket_shared | UNDEFINED
+
+#uri
+struct apr_uri_t | APR::URI
+
+#uuid
+struct apr_uuid_t | APR::UUID
+
+#crypto stuff
+struct apr_md5_ctx_t | APR::MD5
+struct apr_md4_ctx_t | UNDEFINED
+struct apr_sha1_ctx_t | APR::SHA1
+
+#getopt
+struct apr_getopt_t | APR::Getopt
+struct apr_getopt_option_t | APR::GetoptOption
+
+#dso
+struct apr_dso_handle_t | UNDEFINED
+struct apr_dso_handle_sym_t | UNDEFINED
+struct apr_os_dso_handle_t | UNDEFINED
+
+#file stuff
+struct apr_file_t | UNDEFINED
+struct apr_os_file_t | UNDEFINED
+struct apr_dir_t | UNDEFINED
+struct apr_os_dir_t | UNDEFINED
+apr_seek_where_t | UNDEFINED
+struct apr_pollfd_t | UNDEFINED
+apr_fileperms_t | IV
+struct apr_finfo_t | APR::Finfo
+apr_filetype_e | IV
+apr_dev_t | NV
+apr_ino_t | IV
+
+#process stuff
+struct apr_proc_t | APR::Process
+struct apr_procattr_t | UNDEFINED
+enum kill_conditions
+apr_os_proc_t | UNDEFINED
+apr_cmdtype_e | UNDEFINED
+apr_wait_how_e | UNDEFINED
+apr_other_child_rec_t | UNDEFINED
+
+#time stuff
+struct apr_time_exp_t | APR::ExplodedTime
+struct apr_os_exp_time_t | UNDEFINED
+struct apr_os_imp_time_t | NOTIMPL
+
+#data structure stuff
+struct apr_array_header_t | APR::ArrayHeader
+struct apr_table_t | APR::Table
+apr_table_entry_t | APR::TableEntry
+struct apr_hash_t | APR::Hash
+apr_hash_index_t | APR::HashIndex
+
+#lock stuff
+apr_locktype_e | IV
+apr_lockmech_e | IV
+
+#thread stuff
+struct apr_threadkey_t | UNDEFINED
+struct apr_os_threadkey_t | UNDEFINED
+typedef apr_os_thread_t | UNDEFINED
+struct apr_thread_t | UNDEFINED
+apr_thread_start_t | UNDEFINED
+struct apr_threadattr_t | UNDEFINED
+struct apr_thread_mutex_t | APR::ThreadMutex
+struct apr_thread_once_t | UNDEFINED
+struct apr_thread_cond_t | UNDEFINED
+struct apr_thread_rwlock_t | APR::ThreadRWLock
+
+#signal stuff
+apr_signum_t | UNDEFINED
+apr_sigfunc_t | UNDEFINED
+
+#shared memory stuff
+struct apr_mmap_t | APR::Mmap
+
+#xml stuff
+struct apr_text | UNDEFINED
+struct apr_text_header | UNDEFINED
+struct apr_xml_elem | UNDEFINED
+struct apr_xml_doc | UNDEFINED
+struct apr_xml_attr | UNDEFINED
+struct apr_xml_ns_scope | UNDEFINED
+struct apr_xml_parser | UNDEFINED
+
+#integer stuff
+apr_int16_t | IV
+apr_int32_t | IV
+apr_int64_t | NV
+apr_uint16_t | IV
+apr_uint32_t | IV
+apr_uint64_t | NV
+apr_socklen_t | IV
+apr_ssize_t | IV
+apr_size_t | UV
+apr_time_t | NV
+apr_interval_time_t | NV
+apr_gid_t | IV
+apr_uid_t | IV
+apr_off_t | IV
+apr_byte_t | CHAR
+apr_status_t | IV #dualvar?
+
+#misc stuff
+apr_hdtr_t | NOTIMPL #sendfile
+apr_vformatter_buff_t | NOTIMPL
+
+#dbm stuff
+apr_datum_t | NOTIMPL #sdbm
+struct apr_dbm_t | NOTIMPL #sdbm
+struct apr_sdbm_t | NOTIMPL
+struct apr_sdbm_datum_t| NOTIMPL
diff --git a/2_0_13/xs/maps/modperl_functions.map b/2_0_13/xs/maps/modperl_functions.map
new file mode 100644
index 0000000..66047aa
--- /dev/null
+++ b/2_0_13/xs/maps/modperl_functions.map
@@ -0,0 +1,183 @@
+########## mod_perl specific functions ##########
+
+# for mapping see %ModPerl::MapUtil::disabled_map in
+# lib/ModPerl/MapUtil.pm
+
+MODULE=ModPerl::Util
+ mpxs_ModPerl__Util_untaint | | ...
+ SV *:DEFINE_current_perl_id
+ char *:DEFINE_current_callback
+ DEFINE_unload_package_xs | | const char *:package
+
+MODULE=ModPerl::Global
+ mpxs_ModPerl__Global_special_list_call
+ mpxs_ModPerl__Global_special_list_clear
+ mpxs_ModPerl__Global_special_list_register
+
+MODULE=Apache2::RequestRec PACKAGE=Apache2::RequestRec
+ mpxs_Apache2__RequestRec_content_type | | r, type=(SV *)NULL
+ mpxs_Apache2__RequestRec_proxyreq | | r, val=(SV *)NULL
+ mpxs_Apache2__RequestRec_subprocess_env | | r, key=NULL, val=(SV *)NULL
+ mpxs_Apache2__RequestRec_finfo | | r, finfo=NULL
+ mpxs_Apache2__RequestRec_handler | | ...
+ mpxs_Apache2__RequestRec_content_languages | | r, languages=(SV *)NULL
+
+#_if_ do { \
+ Apache2::Build->build_config \
+ ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \
+ ? ($1*1000+$2)*1000+$3 \
+ : die "Cannot get httpd version"; \
+ } > 2003000
+MODULE=Apache2::ServerRec PACKAGE=Apache2::ServerRec
+ mpxs_Apache2__ServerRec_is_virtual | | server_rec *:s, val=(SV *)NULL
+#_end_
+
+MODULE=Apache2::RequestUtil PACKAGE=guess
+ mpxs_Apache2__RequestRec_push_handlers
+ mpxs_Apache2__RequestRec_set_handlers
+ mpxs_Apache2__RequestRec_get_handlers
+ mpxs_Apache2__RequestRec_is_perl_option_enabled
+ mpxs_Apache2__RequestRec_location
+ mpxs_Apache2__RequestRec_as_string
+ mpxs_Apache2__RequestRec_pnotes | | r, key=(SV *)NULL, val=(SV *)NULL
+ mpxs_Apache2__RequestRec_pnotes_kill | | r
+ mpxs_Apache2__RequestRec_add_config | | r, lines, override=MP_HTTPD_OVERRIDE_HTACCESS, path=NULL, override_options=MP_HTTPD_OVERRIDE_OPTS_UNSET
+ mpxs_Apache2__RequestRec_document_root | | r, new_root=(SV *)NULL
+ mpxs_Apache2__RequestRec_child_terminate
+
+ #protocol module helpers
+ mpxs_Apache2__RequestRec_location_merge
+ mpxs_Apache2__RequestRec_set_basic_credentials
+ mpxs_Apache2__RequestRec_no_cache | | r, flag=(SV *)NULL
+
+PACKAGE=Apache2::RequestRec
+ mpxs_Apache2__RequestRec_new | | classname, c, base_pool_sv=(SV *)NULL
+ SV *:DEFINE_dir_config | | request_rec *:r, char *:key=NULL, SV *:sv_val=(SV *)NULL
+ SV *:DEFINE_slurp_filename | | request_rec *:r, int:tainted=1
+
+MODULE=Apache2::RequestUtil PACKAGE=Apache2::RequestUtil
+ mpxs_Apache2__RequestUtil_request | | classname, svr=(SV *)NULL
+
+MODULE=Apache2::RequestIO PACKAGE=Apache2::RequestRec
+ SV *:DEFINE_TIEHANDLE | | SV *:stashsv, SV *:sv=(SV *)NULL
+ SV *:DEFINE_PRINT | | ...
+ apr_size_t:DEFINE_PRINTF | | ...
+ SV *:DEFINE_BINMODE | | request_rec *:r
+ SV *:DEFINE_CLOSE | | request_rec *:r
+ SV *:DEFINE_UNTIE | | request_rec *:r, int:refcnt
+ mpxs_Apache2__RequestRec_sendfile | | r, filename=r->filename, offset=0, len=0
+ mpxs_Apache2__RequestRec_read | | r, buffer, len, offset=0
+ SV *:DEFINE_READ | | request_rec *:r, SV *:buffer, apr_size_t:len, apr_off_t:offset=0
+ mpxs_Apache2__RequestRec_write | | r, buffer, len=-1, offset=0
+ mpxs_Apache2__RequestRec_print | | ...
+ apr_size_t:DEFINE_WRITE | | \
+ request_rec *:r, SV *:buffer, apr_size_t:len=-1, apr_off_t:offset=0
+ mpxs_Apache2__RequestRec_rflush | | ...
+ mpxs_Apache2__RequestRec_GETC
+ mpxs_Apache2__RequestRec_OPEN | | SV *:self, SV *:arg1, SV *:arg2=(SV *)NULL
+ mpxs_Apache2__RequestRec_FILENO
+
+MODULE=Apache2::Response PACKAGE=Apache2::RequestRec
+DEFINE_send_cgi_header | | request_rec *:r, SV *:buffer
+ mpxs_Apache2__RequestRec_set_last_modified | | r, mtime=0
+
+
+MODULE=Apache2::ServerUtil PACKAGE=guess
+ mpxs_Apache2__ServerRec_push_handlers
+ mpxs_Apache2__ServerRec_set_handlers
+ mpxs_Apache2__ServerRec_get_handlers
+ mpxs_Apache2__ServerRec_is_perl_option_enabled
+ mpxs_Apache2__ServerRec_add_config
+
+MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerRec
+ SV *:DEFINE_dir_config | | server_rec *:s, char *:key=NULL, SV *:sv_val=(SV *)NULL
+
+MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerUtil
+ mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register | | cv, arg=(SV *)NULL
+ int:DEFINE_restart_count
+
+MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerUtil
+ server_rec *:DEFINE_server | | SV *:classname=(SV *)NULL
+ uid_t:DEFINE_user_id | | SV *:classname=(SV *)NULL
+ gid_t:DEFINE_group_id | | SV *:classname=(SV *)NULL
+
+MODULE=Apache2::Connection
+ mpxs_Apache2__Connection_client_socket | | c, s=NULL
+
+MODULE=Apache2::ConnectionUtil PACKAGE=guess
+ mpxs_Apache2__Connection_pnotes | | c, key=(SV *)NULL, val=(SV *)NULL
+ mpxs_Apache2__Connection_pnotes_kill | | c
+
+MODULE=Apache2::Filter
+ modperl_filter_attributes | MPXS_ | ... | MODIFY_CODE_ATTRIBUTES
+
+ mpxs_Apache2__Filter_print | | ...
+ mpxs_Apache2__Filter_read | | ...
+ mpxs_Apache2__Filter_seen_eos | | ...
+ mpxs_Apache2__Filter_ctx | | filter, data=(SV *)NULL
+ mpxs_Apache2__Filter_remove | | ...
+
+ SV *:DEFINE_TIEHANDLE | | SV *:stashsv, SV *:sv=(SV *)NULL
+ apr_size_t:DEFINE_PRINT | | ...
+
+MODULE=Apache2::Filter PACKAGE=Apache2::RequestRec
+ mpxs_Apache2__RequestRec_add_input_filter
+ mpxs_Apache2__RequestRec_add_output_filter
+
+MODULE=Apache2::Filter PACKAGE=Apache2::Connection
+ mpxs_Apache2__Connection_add_input_filter
+ mpxs_Apache2__Connection_add_output_filter
+
+MODULE=Apache2::Log PACKAGE=Apache2::Log BOOT=1
+
+DEFINE_error | MPXS_Apache2__Log_dispatch | ...
+DEFINE_emerg | MPXS_Apache2__Log_dispatch | ...
+DEFINE_alert | MPXS_Apache2__Log_dispatch | ...
+DEFINE_warn | MPXS_Apache2__Log_dispatch | ...
+DEFINE_notice | MPXS_Apache2__Log_dispatch | ...
+DEFINE_info | MPXS_Apache2__Log_dispatch | ...
+DEFINE_debug | MPXS_Apache2__Log_dispatch | ...
+DEFINE_crit | MPXS_Apache2__Log_dispatch | ...
+DEFINE_LOG_MARK | MPXS_Apache2__Log_LOG_MARK | ...
+
+PACKAGE=Apache2::RequestRec
+SV *:DEFINE_log | | SV *:obj
+DEFINE_log_rerror | MPXS_Apache2__Log_log_xerror | ...
+DEFINE_log_error | MPXS_Apache2__Log_log_error | ...
+DEFINE_warn | MPXS_Apache2__Log_log_error | ...
+DEFINE_log_reason | modperl_log_reason | request_rec *:r, char *:msg, char *:file=r->uri
+
+PACKAGE=Apache2::ServerRec
+SV *:DEFINE_log | | SV *:obj
+DEFINE_log_serror | MPXS_Apache2__Log_log_xerror | ...
+DEFINE_log_error | MPXS_Apache2__Log_log_error | ...
+DEFINE_warn | MPXS_Apache2__Log_log_error | ...
+
+MODULE=Apache2::SubProcess PACKAGE=Apache2::RequestRec
+ # ap_subprocess_ won't work
+ modperl_spawn_proc_prog | MPXS_ | ... | spawn_proc_prog
+
+MODULE=Apache2::Directive
+ mpxs_Apache2__Directive_as_string
+ mpxs_Apache2__Directive_as_hash
+ DEFINE_lookup | MPXS_Apache2__Directive_lookup | ...
+
+MODULE=Apache2::CmdParms
+ ap_check_cmd_context
+ ap_method_is_limited
+ mpxs_Apache2__CmdParms_info
+ mpxs_Apache2__CmdParms_add_config
+ mpxs_Apache2__CmdParms_override_opts
+
+MODULE=Apache2::MPM PACKAGE=Apache2::MPM BOOT=1
+ mpxs_Apache2__MPM_query
+
+MODULE=Apache2::Access PACKAGE=guess
+ mpxs_Apache2__RequestRec_allow_override_opts
+
+#_if_ do {use Apache2::Build; Apache2::Build::PERL_HAS_ITHREADS}
+
+MODULE=ModPerl::Interpreter
+ mpxs_ModPerl__Interpreter_current | | class=Nullsv
+
+#_end_
diff --git a/2_0_13/xs/maps/modperl_structures.map b/2_0_13/xs/maps/modperl_structures.map
new file mode 100644
index 0000000..9157ee3
--- /dev/null
+++ b/2_0_13/xs/maps/modperl_structures.map
@@ -0,0 +1,44 @@
+########## ModPerl structures ##########
+
+# for mapping see %ModPerl::MapUtil::disabled_map in
+# lib/ModPerl/MapUtil.pm
+
+#_if_ do {use Apache2::Build; Apache2::Build::PERL_HAS_ITHREADS}
+
+<modperl_interp_t>
+< mip
+< perl
+< num_requests
+< flags
+- ccfg
+< refcnt
+- tid
+</modperl_interp_t>
+
+<modperl_interp_pool_t>
+< server
+< tipool
+< parent
+</modperl_interp_pool_t>
+
+<modperl_tipool_t>
+- tiplock
+- available
+- idle
+- busy
+< in_use
+< size
+- data
+< cfg
+- func
+</modperl_tipool_t>
+
+<modperl_tipool_config_t>
+< start
+< min_spare
+< max_spare
+< max
+< max_requests
+</modperl_tipool_config_t>
+
+#_end_
diff --git a/2_0_13/xs/maps/modperl_types.map b/2_0_13/xs/maps/modperl_types.map
new file mode 100644
index 0000000..b251940
--- /dev/null
+++ b/2_0_13/xs/maps/modperl_types.map
@@ -0,0 +1,24 @@
+########## mod_perl types ##########
+
+struct modperl_filter_t | Apache2::OutputFilter
+
+#_if_ do {use Apache2::Build; Apache2::Build::PERL_HAS_ITHREADS}
+
+struct modperl_interp_t | ModPerl::Interpreter
+struct modperl_interp_pool_t | ModPerl::InterpPool
+struct modperl_tipool_t | ModPerl::TiPool
+struct modperl_tipool_config_t | ModPerl::TiPoolConfig
+PerlInterpreter * | IV
+
+#_end_
+
+########## Perl types ##########
+
+SV * | SV
+I32 | IV
+I32 * | IV
+U16 | UV
+U16 * | UV
+U32 | UV
+U32 * | UV
+
diff --git a/2_0_13/xs/modperl_xs_util.h b/2_0_13/xs/modperl_xs_util.h
new file mode 100644
index 0000000..749352e
--- /dev/null
+++ b/2_0_13/xs/modperl_xs_util.h
@@ -0,0 +1,167 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MODPERL_XS_H
+#define MODPERL_XS_H
+
+/* XXX: should be part of generation */
+#undef mp_xs_sv2_r /* defined in modperl_xs_sv_convert.h */
+#define mp_xs_sv2_r(sv) modperl_sv2request_rec(aTHX_ sv)
+
+#undef mp_xs_sv2_APR__Table
+#define mp_xs_sv2_APR__Table(sv) \
+ (apr_table_t *)modperl_hash_tied_object(aTHX_ "APR::Table", sv)
+
+#define mpxs_Apache2__RequestRec_pool(r) r->pool
+#define mpxs_Apache2__Connection_pool(c) c->pool
+#define mpxs_Apache2__URI_pool(u) ((modperl_uri_t *)u)->pool
+#define mpxs_APR__URI_pool(u) ((modperl_uri_t *)u)->pool
+
+#ifndef dAX
+# define dAX I32 ax = mark - PL_stack_base + 1
+#endif
+
+#ifndef dITEMS
+# define dITEMS I32 items = SP - MARK
+#endif
+
+#define mpxs_PPCODE(code) STMT_START { \
+ SP -= items; \
+ code; \
+ PUTBACK; \
+} STMT_END
+
+#define PUSHs_mortal_iv(iv) PUSHs(sv_2mortal(newSViv(iv)))
+#define PUSHs_mortal_pv(pv) PUSHs(sv_2mortal(newSVpv((char *)pv,0)))
+
+#define XPUSHs_mortal_iv(iv) EXTEND(SP, 1); PUSHs_mortal_iv(iv)
+#define XPUSHs_mortal_pv(pv) EXTEND(SP, 1); PUSHs_mortal_pv(pv)
+
+/* XXX: replace the old mpxs_sv_ macros with MP_Sv macros */
+
+#define mpxs_sv_grow(sv, len) MP_SvGROW(sv, len)
+
+#define mpxs_sv_cur_set(sv, len) MP_SvCUR_set(sv, len)
+
+#define mpxs_set_targ(func, arg) \
+ STMT_START { \
+ dXSTARG; \
+ XSprePUSH; \
+ func(aTHX_ TARG, arg); \
+ PUSHTARG; \
+ XSRETURN(1); \
+} STMT_END
+
+#define mpxs_cv_name() \
+ HvNAME(GvSTASH(CvGV(cv))), GvNAME(CvGV(cv))
+
+#define mpxs_sv_is_object(sv) \
+ (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG))
+
+#define mpxs_sv_object_deref(sv, type) \
+ (mpxs_sv_is_object(sv) ? \
+ INT2PTR(type *, SvIVX((SV*)SvRV(sv))) : NULL)
+
+#define mpxs_sv2_obj(obj, sv) \
+ (obj = mp_xs_sv2_##obj(sv))
+
+#define mpxs_usage_items_1(arg) \
+ if (items != 1) { \
+ Perl_croak(aTHX_ "usage: %s::%s(%s)", \
+ mpxs_cv_name(), arg); \
+ }
+
+#define mpxs_usage_va(i, obj, msg) \
+ if ((items < i) || !(mpxs_sv2_obj(obj, *MARK))) { \
+ Perl_croak(aTHX_ "usage: %s", msg); \
+ } \
+ MARK++
+
+#define mpxs_usage_va_1(obj, msg) mpxs_usage_va(1, obj, msg)
+
+#define mpxs_usage_va_2(obj, arg, msg) \
+ mpxs_usage_va(2, obj, msg); \
+ arg = *MARK++
+
+#define mpxs_write_loop(func, obj, name) \
+ while (MARK <= SP) { \
+ apr_size_t wlen; \
+ char *buf = SvPV(*MARK, wlen); \
+ MP_TRACE_o(MP_FUNC, "%d bytes [%s]", wlen, buf); \
+ MP_RUN_CROAK(func(aTHX_ obj, buf, &wlen), name); \
+ bytes += wlen; \
+ MARK++; \
+ }
+
+/* custom pool objects created by modperl users (not internal like
+ * r->pool) are marked by magic in SvRV(obj)
+ */
+#define mpxs_pool_is_custom(pool) (mg_find(pool, PERL_MAGIC_ext) != NULL)
+
+/* several methods need to ensure that the pool that they take as an
+ * object doesn't go out of scope before the object that they return,
+ * since if this happens, the data contained in the later object
+ * becomes corrupted. this macro is used in various xs files where
+ * it's needed */
+#if ((PERL_REVISION == 5) && (PERL_VERSION >= 8))
+ /* sometimes the added magic is the second one (e.g. in case when
+ * the object is generated by modperl_hash_tie, so under 5.8+
+ * need to use sv_magicext, since sv_magicext does only one magic
+ * of the same type at 5.8+ */
+#define mpxs_add_pool_magic_doit(obj, pool_obj) \
+ sv_magicext(SvRV(obj), pool_obj, PERL_MAGIC_ext, NULL, (char *)NULL, -1)
+#else
+#define mpxs_add_pool_magic_doit(obj, pool_obj) \
+ sv_magic(SvRV(obj), pool_obj, PERL_MAGIC_ext, (char *)NULL, -1)
+#endif
+
+/* add dependency magic only for custom pools. there are all kind of
+ * complications when more than one magic of the same type(in this
+ * case PERL_MAGIC_ext is added), luckily most of the PERL_MAGIC_ext
+ * magic used by modperl-core, uses (SV *)NULL as mg->mg_obj, therefore
+ * the following code tries to workaround the multiple magic issue, by
+ * simply hanging the pool object into the unused slot, incrementing
+ * its refcnt just like sv_magic does internally. In case we ever hit
+ * magic which already has mg->mg_obj taken we will deal with that,
+ * for now we just croak in such a case.
+ */
+#define mpxs_add_pool_magic(obj, pool_obj) \
+ if (mpxs_pool_is_custom(SvRV(pool_obj))) { \
+ MAGIC *mg = mg_find(SvRV(obj), PERL_MAGIC_ext); \
+ if (mg) { \
+ if (mg->mg_obj == (SV *)NULL) { \
+ mg->mg_obj = SvREFCNT_inc(SvRV(pool_obj)); \
+ mg->mg_flags |= MGf_REFCOUNTED; \
+ } \
+ else { \
+ Perl_croak(aTHX_ "Fixme: don't know how to " \
+ "handle magic w/ occupied mg->mg_obj"); \
+ } \
+ } \
+ else { \
+ mpxs_add_pool_magic_doit(obj, SvRV(pool_obj)); \
+ } \
+ }
+
+
+#endif /* MODPERL_XS_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/2_0_13/xs/tables/current/APR/FunctionTable.pm b/2_0_13/xs/tables/current/APR/FunctionTable.pm
new file mode 100644
index 0000000..6e3b404
--- /dev/null
+++ b/2_0_13/xs/tables/current/APR/FunctionTable.pm
@@ -0,0 +1,229 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package APR::FunctionTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: this file was manually generated on
+# ! Tue Jun 22 22:00:00 2004
+# ! It contains a subset of functions appearing in
+# ! ModPerl::FunctionTable used to build APR.so
+# ! Eventually this will be autogenerated by
+# ! Apache::ParseSource
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$APR::FunctionTable = [
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_level_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'level'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_logfile_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile_new'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned long',
+ 'name' => 'modperl_debug_level',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_hash_tie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_hash_tied_object',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_sv_setref_uv',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'rv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'UV',
+ 'name' => 'uv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_uri_t *',
+ 'name' => 'modperl_uri_new',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_gensym',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'pack'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_error_strerror',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_croak',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_unselect',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'modperl_bucket_sv_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+];
+
+1;
diff --git a/2_0_13/xs/tables/current/Apache2/ConstantsTable.pm b/2_0_13/xs/tables/current/Apache2/ConstantsTable.pm
new file mode 100644
index 0000000..9ea2d43
--- /dev/null
+++ b/2_0_13/xs/tables/current/Apache2/ConstantsTable.pm
@@ -0,0 +1,474 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package Apache2::ConstantsTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by Apache2::ParseSource/0.02
+# ! Mon May 23 14:15:32 2005
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$Apache2::ConstantsTable = {
+ 'ModPerl' => {
+ 'common' => [
+ 'MODPERL_RC_EXIT'
+ ]
+ },
+ 'Apache2::Const' => {
+ 'types' => [
+ 'DIR_MAGIC_TYPE'
+ ],
+ 'satisfy' => [
+ 'SATISFY_ALL',
+ 'SATISFY_ANY',
+ 'SATISFY_NOSPEC'
+ ],
+ 'remotehost' => [
+ 'REMOTE_HOST',
+ 'REMOTE_NAME',
+ 'REMOTE_NOLOOKUP',
+ 'REMOTE_DOUBLE_REV'
+ ],
+ 'platform' => [
+ 'LF',
+ 'CR',
+ 'CRLF'
+ ],
+ 'override' => [
+ 'OR_NONE',
+ 'OR_LIMIT',
+ 'OR_OPTIONS',
+ 'OR_FILEINFO',
+ 'OR_AUTHCFG',
+ 'OR_INDEXES',
+ 'OR_UNSET',
+ 'ACCESS_CONF',
+ 'RSRC_CONF',
+ 'EXEC_ON_READ',
+ 'OR_ALL'
+ ],
+ 'options' => [
+ 'OPT_NONE',
+ 'OPT_INDEXES',
+ 'OPT_INCLUDES',
+ 'OPT_SYM_LINKS',
+ 'OPT_EXECCGI',
+ 'OPT_UNSET',
+ 'OPT_INCNOEXEC',
+ 'OPT_SYM_OWNER',
+ 'OPT_MULTI',
+ 'OPT_ALL'
+ ],
+ 'mpmq' => [
+ 'AP_MPMQ_NOT_SUPPORTED',
+ 'AP_MPMQ_STATIC',
+ 'AP_MPMQ_DYNAMIC',
+ 'AP_MPMQ_STARTING',
+ 'AP_MPMQ_RUNNING',
+ 'AP_MPMQ_STOPPING',
+ 'AP_MPMQ_MAX_DAEMON_USED',
+ 'AP_MPMQ_IS_THREADED',
+ 'AP_MPMQ_IS_FORKED',
+ 'AP_MPMQ_HARD_LIMIT_DAEMONS',
+ 'AP_MPMQ_HARD_LIMIT_THREADS',
+ 'AP_MPMQ_MAX_THREADS',
+ 'AP_MPMQ_MIN_SPARE_DAEMONS',
+ 'AP_MPMQ_MIN_SPARE_THREADS',
+ 'AP_MPMQ_MAX_SPARE_DAEMONS',
+ 'AP_MPMQ_MAX_SPARE_THREADS',
+ 'AP_MPMQ_MAX_REQUESTS_DAEMON',
+ 'AP_MPMQ_MAX_DAEMONS',
+ 'AP_MPMQ_MPM_STATE'
+ ],
+ 'methods' => [
+ 'M_GET',
+ 'M_PUT',
+ 'M_POST',
+ 'M_DELETE',
+ 'M_CONNECT',
+ 'M_OPTIONS',
+ 'M_TRACE',
+ 'M_PATCH',
+ 'M_PROPFIND',
+ 'M_PROPPATCH',
+ 'M_MKCOL',
+ 'M_COPY',
+ 'M_MOVE',
+ 'M_LOCK',
+ 'M_UNLOCK',
+ 'M_VERSION_CONTROL',
+ 'M_CHECKOUT',
+ 'M_UNCHECKOUT',
+ 'M_CHECKIN',
+ 'M_UPDATE',
+ 'M_LABEL',
+ 'M_REPORT',
+ 'M_MKWORKSPACE',
+ 'M_MKACTIVITY',
+ 'M_BASELINE_CONTROL',
+ 'M_MERGE',
+ 'M_INVALID',
+ 'METHODS'
+ ],
+ 'log' => [
+ 'APLOG_EMERG',
+ 'APLOG_ALERT',
+ 'APLOG_CRIT',
+ 'APLOG_ERR',
+ 'APLOG_WARNING',
+ 'APLOG_NOTICE',
+ 'APLOG_INFO',
+ 'APLOG_DEBUG',
+ 'APLOG_LEVELMASK',
+ 'APLOG_TOCLIENT',
+ 'APLOG_STARTUP'
+ ],
+ 'input_mode' => [
+ 'AP_MODE_READBYTES',
+ 'AP_MODE_GETLINE',
+ 'AP_MODE_EATCRLF',
+ 'AP_MODE_SPECULATIVE',
+ 'AP_MODE_EXHAUSTIVE',
+ 'AP_MODE_INIT'
+ ],
+ 'http' => [
+ 'HTTP_CONTINUE',
+ 'HTTP_SWITCHING_PROTOCOLS',
+ 'HTTP_PROCESSING',
+ 'HTTP_OK',
+ 'HTTP_CREATED',
+ 'HTTP_ACCEPTED',
+ 'HTTP_NON_AUTHORITATIVE',
+ 'HTTP_NO_CONTENT',
+ 'HTTP_RESET_CONTENT',
+ 'HTTP_PARTIAL_CONTENT',
+ 'HTTP_MULTI_STATUS',
+ 'HTTP_MULTIPLE_CHOICES',
+ 'HTTP_MOVED_PERMANENTLY',
+ 'HTTP_MOVED_TEMPORARILY',
+ 'HTTP_SEE_OTHER',
+ 'HTTP_NOT_MODIFIED',
+ 'HTTP_USE_PROXY',
+ 'HTTP_TEMPORARY_REDIRECT',
+ 'HTTP_BAD_REQUEST',
+ 'HTTP_UNAUTHORIZED',
+ 'HTTP_PAYMENT_REQUIRED',
+ 'HTTP_FORBIDDEN',
+ 'HTTP_NOT_FOUND',
+ 'HTTP_METHOD_NOT_ALLOWED',
+ 'HTTP_NOT_ACCEPTABLE',
+ 'HTTP_PROXY_AUTHENTICATION_REQUIRED',
+ 'HTTP_REQUEST_TIME_OUT',
+ 'HTTP_CONFLICT',
+ 'HTTP_GONE',
+ 'HTTP_LENGTH_REQUIRED',
+ 'HTTP_PRECONDITION_FAILED',
+ 'HTTP_REQUEST_ENTITY_TOO_LARGE',
+ 'HTTP_REQUEST_URI_TOO_LARGE',
+ 'HTTP_UNSUPPORTED_MEDIA_TYPE',
+ 'HTTP_RANGE_NOT_SATISFIABLE',
+ 'HTTP_EXPECTATION_FAILED',
+ 'HTTP_UNPROCESSABLE_ENTITY',
+ 'HTTP_LOCKED',
+ 'HTTP_FAILED_DEPENDENCY',
+ 'HTTP_UPGRADE_REQUIRED',
+ 'HTTP_INTERNAL_SERVER_ERROR',
+ 'HTTP_NOT_IMPLEMENTED',
+ 'HTTP_BAD_GATEWAY',
+ 'HTTP_SERVICE_UNAVAILABLE',
+ 'HTTP_GATEWAY_TIME_OUT',
+ 'HTTP_VARIANT_ALSO_VARIES',
+ 'HTTP_INSUFFICIENT_STORAGE',
+ 'HTTP_NOT_EXTENDED'
+ ],
+ 'filter_type' => [
+ 'AP_FTYPE_RESOURCE',
+ 'AP_FTYPE_CONTENT_SET',
+ 'AP_FTYPE_PROTOCOL',
+ 'AP_FTYPE_TRANSCODE',
+ 'AP_FTYPE_CONNECTION',
+ 'AP_FTYPE_NETWORK'
+ ],
+ 'context' => [
+ 'NOT_IN_VIRTUALHOST',
+ 'NOT_IN_LIMIT',
+ 'NOT_IN_DIRECTORY',
+ 'NOT_IN_LOCATION',
+ 'NOT_IN_FILES',
+ 'NOT_IN_DIR_LOC_FILE',
+ 'GLOBAL_ONLY'
+ ],
+ 'conn_keepalive' => [
+ 'AP_CONN_UNKNOWN',
+ 'AP_CONN_CLOSE',
+ 'AP_CONN_KEEPALIVE'
+ ],
+ 'config' => [
+ 'DECLINE_CMD'
+ ],
+ 'common' => [
+ 'DECLINED',
+ 'DONE',
+ 'OK',
+ 'NOT_FOUND',
+ 'FORBIDDEN',
+ 'AUTH_REQUIRED',
+ 'SERVER_ERROR',
+ 'REDIRECT'
+ ],
+ 'cmd_how' => [
+ 'RAW_ARGS',
+ 'TAKE1',
+ 'TAKE2',
+ 'ITERATE',
+ 'ITERATE2',
+ 'FLAG',
+ 'NO_ARGS',
+ 'TAKE12',
+ 'TAKE3',
+ 'TAKE23',
+ 'TAKE123',
+ 'TAKE13'
+ ],
+ 'proxy' => [
+ 'PROXYREQ_REVERSE',
+ 'PROXYREQ_NONE',
+ 'PROXYREQ_PROXY',
+ 'PROXYREQ_RESPONSE',
+ ],
+ },
+ 'APR::Const' => {
+ 'uri' => [
+ 'APR_URI_FTP_DEFAULT_PORT',
+ 'APR_URI_SSH_DEFAULT_PORT',
+ 'APR_URI_TELNET_DEFAULT_PORT',
+ 'APR_URI_GOPHER_DEFAULT_PORT',
+ 'APR_URI_HTTP_DEFAULT_PORT',
+ 'APR_URI_POP_DEFAULT_PORT',
+ 'APR_URI_NNTP_DEFAULT_PORT',
+ 'APR_URI_IMAP_DEFAULT_PORT',
+ 'APR_URI_PROSPERO_DEFAULT_PORT',
+ 'APR_URI_WAIS_DEFAULT_PORT',
+ 'APR_URI_LDAP_DEFAULT_PORT',
+ 'APR_URI_HTTPS_DEFAULT_PORT',
+ 'APR_URI_RTSP_DEFAULT_PORT',
+ 'APR_URI_SNEWS_DEFAULT_PORT',
+ 'APR_URI_ACAP_DEFAULT_PORT',
+ 'APR_URI_NFS_DEFAULT_PORT',
+ 'APR_URI_TIP_DEFAULT_PORT',
+ 'APR_URI_SIP_DEFAULT_PORT',
+ 'APR_URI_UNP_OMITSITEPART',
+ 'APR_URI_UNP_OMITUSER',
+ 'APR_URI_UNP_OMITPASSWORD',
+ 'APR_URI_UNP_OMITUSERINFO',
+ 'APR_URI_UNP_REVEALPASSWORD',
+ 'APR_URI_UNP_OMITPATHINFO',
+ 'APR_URI_UNP_OMITQUERY'
+ ],
+ 'table' => [
+ 'APR_OVERLAP_TABLES_SET',
+ 'APR_OVERLAP_TABLES_MERGE'
+ ],
+ 'status' => [
+ 'APR_TIMEUP'
+ ],
+ 'socket' => [
+ 'APR_SO_LINGER',
+ 'APR_SO_KEEPALIVE',
+ 'APR_SO_DEBUG',
+ 'APR_SO_NONBLOCK',
+ 'APR_SO_REUSEADDR',
+ 'APR_SO_SNDBUF',
+ 'APR_SO_RCVBUF',
+ 'APR_SO_DISCONNECTED'
+ ],
+ 'shutdown_how' => [
+ 'APR_SHUTDOWN_READ',
+ 'APR_SHUTDOWN_WRITE',
+ 'APR_SHUTDOWN_READWRITE'
+ ],
+ 'read_type' => [
+ 'APR_BLOCK_READ',
+ 'APR_NONBLOCK_READ'
+ ],
+ 'poll' => [
+ 'APR_POLLIN',
+ 'APR_POLLPRI',
+ 'APR_POLLOUT',
+ 'APR_POLLERR',
+ 'APR_POLLHUP',
+ 'APR_POLLNVAL'
+ ],
+ 'lockmech' => [
+ 'APR_LOCK_FCNTL',
+ 'APR_LOCK_FLOCK',
+ 'APR_LOCK_SYSVSEM',
+ 'APR_LOCK_PROC_PTHREAD',
+ 'APR_LOCK_POSIXSEM',
+ 'APR_LOCK_DEFAULT'
+ ],
+ 'limit' => [
+ 'APR_LIMIT_CPU',
+ 'APR_LIMIT_MEM',
+ 'APR_LIMIT_NPROC',
+ 'APR_LIMIT_NOFILE'
+ ],
+ 'hook' => [
+ 'APR_HOOK_REALLY_FIRST',
+ 'APR_HOOK_FIRST',
+ 'APR_HOOK_MIDDLE',
+ 'APR_HOOK_LAST',
+ 'APR_HOOK_REALLY_LAST'
+ ],
+ 'fprot' => [
+ 'APR_FPROT_USETID',
+ 'APR_FPROT_UREAD',
+ 'APR_FPROT_UWRITE',
+ 'APR_FPROT_UEXECUTE',
+ 'APR_FPROT_GSETID',
+ 'APR_FPROT_GREAD',
+ 'APR_FPROT_GWRITE',
+ 'APR_FPROT_GEXECUTE',
+ 'APR_FPROT_WSTICKY',
+ 'APR_FPROT_WREAD',
+ 'APR_FPROT_WWRITE',
+ 'APR_FPROT_WEXECUTE',
+ 'APR_FPROT_OS_DEFAULT'
+ ],
+ 'fopen' => [
+ 'APR_FOPEN_READ',
+ 'APR_FOPEN_WRITE',
+ 'APR_FOPEN_CREATE',
+ 'APR_FOPEN_APPEND',
+ 'APR_FOPEN_TRUNCATE',
+ 'APR_FOPEN_BINARY',
+ 'APR_FOPEN_EXCL',
+ 'APR_FOPEN_BUFFERED',
+ 'APR_FOPEN_DELONCLOSE',
+ 'APR_FOPEN_XTHREAD',
+ 'APR_FOPEN_SHARELOCK',
+ 'APR_FOPEN_NOCLEANUP',
+ 'APR_FOPEN_SENDFILE_ENABLED',
+ 'APR_FOPEN_LARGEFILE'
+ ],
+ 'flock' => [
+ 'APR_FLOCK_SHARED',
+ 'APR_FLOCK_EXCLUSIVE',
+ 'APR_FLOCK_TYPEMASK',
+ 'APR_FLOCK_NONBLOCK'
+ ],
+ 'finfo' => [
+ 'APR_FINFO_LINK',
+ 'APR_FINFO_MTIME',
+ 'APR_FINFO_CTIME',
+ 'APR_FINFO_ATIME',
+ 'APR_FINFO_SIZE',
+ 'APR_FINFO_CSIZE',
+ 'APR_FINFO_DEV',
+ 'APR_FINFO_INODE',
+ 'APR_FINFO_NLINK',
+ 'APR_FINFO_TYPE',
+ 'APR_FINFO_USER',
+ 'APR_FINFO_GROUP',
+ 'APR_FINFO_UPROT',
+ 'APR_FINFO_GPROT',
+ 'APR_FINFO_WPROT',
+ 'APR_FINFO_ICASE',
+ 'APR_FINFO_NAME',
+ 'APR_FINFO_MIN',
+ 'APR_FINFO_IDENT',
+ 'APR_FINFO_OWNER',
+ 'APR_FINFO_PROT',
+ 'APR_FINFO_NORM',
+ 'APR_FINFO_DIRENT'
+ ],
+ 'filetype' => [
+ 'APR_FILETYPE_NOFILE',
+ 'APR_FILETYPE_REG',
+ 'APR_FILETYPE_DIR',
+ 'APR_FILETYPE_CHR',
+ 'APR_FILETYPE_BLK',
+ 'APR_FILETYPE_PIPE',
+ 'APR_FILETYPE_LNK',
+ 'APR_FILETYPE_SOCK',
+ 'APR_FILETYPE_UNKFILE'
+ ],
+ 'filepath' => [
+ 'APR_FILEPATH_NOTABOVEROOT',
+ 'APR_FILEPATH_SECUREROOTTEST',
+ 'APR_FILEPATH_SECUREROOT',
+ 'APR_FILEPATH_NOTRELATIVE',
+ 'APR_FILEPATH_NOTABSOLUTE',
+ 'APR_FILEPATH_NATIVE',
+ 'APR_FILEPATH_TRUENAME',
+ 'APR_FILEPATH_ENCODING_UNKNOWN',
+ 'APR_FILEPATH_ENCODING_LOCALE',
+ 'APR_FILEPATH_ENCODING_UTF8'
+ ],
+ 'error' => [
+ 'APR_ENOSTAT',
+ 'APR_ENOPOOL',
+ 'APR_EBADDATE',
+ 'APR_EINVALSOCK',
+ 'APR_ENOPROC',
+ 'APR_ENOTIME',
+ 'APR_ENODIR',
+ 'APR_ENOLOCK',
+ 'APR_ENOPOLL',
+ 'APR_ENOSOCKET',
+ 'APR_ENOTHREAD',
+ 'APR_ENOTHDKEY',
+ 'APR_EGENERAL',
+ 'APR_ENOSHMAVAIL',
+ 'APR_EBADIP',
+ 'APR_EBADMASK',
+ 'APR_EDSOOPEN',
+ 'APR_EABSOLUTE',
+ 'APR_ERELATIVE',
+ 'APR_EINCOMPLETE',
+ 'APR_EABOVEROOT',
+ 'APR_EBADPATH',
+ 'APR_EPATHWILD',
+ 'APR_ESYMNOTFOUND',
+ 'APR_EPROC_UNKNOWN',
+ 'APR_EOF',
+ 'APR_EINIT',
+ 'APR_ENOTIMPL',
+ 'APR_EMISMATCH',
+ 'APR_EBUSY',
+ 'APR_EACCES',
+ 'APR_EEXIST',
+ 'APR_ENAMETOOLONG',
+ 'APR_ENOENT',
+ 'APR_ENOTDIR',
+ 'APR_ENOSPC',
+ 'APR_ENOMEM',
+ 'APR_EMFILE',
+ 'APR_ENFILE',
+ 'APR_EBADF',
+ 'APR_EINVAL',
+ 'APR_ESPIPE',
+ 'APR_EAGAIN',
+ 'APR_EINTR',
+ 'APR_ENOTSOCK',
+ 'APR_ECONNREFUSED',
+ 'APR_EINPROGRESS',
+ 'APR_ECONNABORTED',
+ 'APR_ECONNRESET',
+ 'APR_ETIMEDOUT',
+ 'APR_EHOSTUNREACH',
+ 'APR_ENETUNREACH',
+ 'APR_EFTYPE',
+ 'APR_EPIPE',
+ 'APR_EXDEV',
+ 'APR_ENOTEMPTY',
+ 'APR_EXCL',
+ 'APR_END'
+ ],
+ 'common' => [
+ 'APR_SUCCESS'
+ ],
+ }
+};
+
+
+1;
diff --git a/2_0_13/xs/tables/current/Apache2/FunctionTable.pm b/2_0_13/xs/tables/current/Apache2/FunctionTable.pm
new file mode 100644
index 0000000..dd06d45
--- /dev/null
+++ b/2_0_13/xs/tables/current/Apache2/FunctionTable.pm
@@ -0,0 +1,15034 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package Apache2::FunctionTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by Apache2::ParseSource/0.02
+# ! Mon May 23 14:15:40 2005
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$Apache2::FunctionTable = [
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_file_conf',
+ 'args' => [
+ {
+ 'type' => 'core_dir_config *',
+ 'name' => 'conf'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'url_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_input_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_loaded_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_add_named_module',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_directive_t *',
+ 'name' => 'ap_add_node',
+ 'args' => [
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'current'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'toadd'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'child'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_output_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_output_filters_by_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_per_dir_conf',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dir_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_per_url_conf',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'url_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_version_component',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'component'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_allow_methods',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reset'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_allow_options',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_allow_overrides',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_allow_standard_methods',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reset'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_auth_name',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_auth_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_basic_http_header',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_eoc_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_eoc_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_error_create',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'error'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_error_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'error'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_build_config',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'conf_pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_build_cont_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'current'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'curr_parent'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'orig_directive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_byterange_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_calc_scoreboard_size',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_cfg_closefile',
+ 'args' => [
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_cfg_getc',
+ 'args' => [
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_cfg_getline',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'bufsize'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_check_cmd_context',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'forbidden'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cleanup_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_clear_method_list',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_close_piped_log',
+ 'args' => [
+ {
+ 'type' => 'piped_log *',
+ 'name' => 'pl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_construct_server',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_construct_url',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_content_length_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_content_type_tolower',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_copy_method_list',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'dest'
+ },
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_core_reorder_directories',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_core_translate',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_count_dirs',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t*',
+ 'name' => 'ap_create_conn_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t *',
+ 'name' => 'ap_create_per_dir_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t*',
+ 'name' => 'ap_create_request_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_create_sb_handle',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t **',
+ 'name' => 'new_sbh'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'child_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'thread_num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_create_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_scoreboard_e',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_custom_response',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_default_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_destroy_sub_req',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_die',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_directory_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_discard_request_body',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_document_root',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_error_log2stderr',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_escape_errorlog_item',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dest'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'buflen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_html',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_logitem',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_path_segment',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_quotes',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'instring'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_shell_cmd',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_exists_config_define',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_exists_scoreboard_image',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_explode_recent_gmt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'tm'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_explode_recent_localtime',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'tm'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fatal_signal_child_setup',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fatal_signal_setup',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fflush',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_field_noparam',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'intype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_file_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_filter_flush',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_finalize_request_protocol',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_finalize_sub_req_protocol',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'sub_r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const command_rec *',
+ 'name' => 'ap_find_command',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const command_rec *',
+ 'name' => 'cmds'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const command_rec *',
+ 'name' => 'ap_find_command_in_modules',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'cmd_name'
+ },
+ {
+ 'type' => 'module **',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_last_token',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tok'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'module *',
+ 'name' => 'ap_find_linked_module',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_list_item',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tok'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_find_module_name',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_token',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tok'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_fini_vhost_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'main_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_fixup_virtual_hosts',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'main_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_flush_conn',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fprintf',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fputstrs',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_get_basic_auth_pw',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'pw'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_get_brigade',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bucket'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'long',
+ 'name' => 'ap_get_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsiz'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_get_input_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_off_t',
+ 'name' => 'ap_get_limit_req_body',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'size_t',
+ 'name' => 'ap_get_limit_xml_body',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_get_list_item',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'field'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_get_local_host',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_mime_headers',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_mime_headers_core',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_get_module_config',
+ 'args' => [
+ {
+ 'type' => 'const ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'const module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_get_output_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_remote_host',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'conn'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dir_config'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'str_is_ip'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_remote_logname',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void **',
+ 'name' => 'ap_get_request_note',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'note_num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'global_score *',
+ 'name' => 'ap_get_scoreboard_global',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'process_score *',
+ 'name' => 'ap_get_scoreboard_process',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'x'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'worker_score *',
+ 'name' => 'ap_get_scoreboard_worker',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'x'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'y'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_built',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_name',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'ap_get_server_port',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_version',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_description',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_banner',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_status_line',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_get_token',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'accept_line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'accept_white'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_getline',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'fold'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_getparents',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_conf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_conf_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_nulls',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_nulls_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_white',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_white_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'gid_t',
+ 'name' => 'ap_gname2id',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_graceful_stop_signalled',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_access_checker',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_auth_checker',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_auth_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_user_id',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_check_user_id_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_child_init',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_child_init_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_create_connection',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_create_connection_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_create_request',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_create_request_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_default_port',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_default_port_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_error_log',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_error_log_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_fixups',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_fixups_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_access_checker',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_auth_checker',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_check_user_id',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_child_init',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_create_connection',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_create_request',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_default_port',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_error_log',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_fixups',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_get_mgmt_items',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_get_suexec_identity',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_handler',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_header_parser',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_http_method',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_insert_error_filter',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_insert_filter',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_log_transaction',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_map_to_storage',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_get_mgmt_items',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_get_mgmt_items_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_open_logs',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_optional_fn_retrieve',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_post_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_post_read_request',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_connection',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_process_connection',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_quick_handler',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_status_hook',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_get_suexec_identity',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_get_suexec_identity_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_translate_name',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_type_checker',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_handler_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_header_parser',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_header_parser_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_http_method',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_http_method_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_insert_error_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_insert_error_filter_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_insert_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_insert_filter_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_log_transaction',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_log_transaction_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_map_to_storage',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_map_to_storage_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_open_logs',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_open_logs_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_optional_fn_retrieve',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_optional_fn_retrieve_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_post_config',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_post_config_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_post_read_request',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_post_read_request_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_config',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_config_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_connection_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_mpm',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_mpm_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_process_connection',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_process_connection_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_quick_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_quick_handler_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_status_hook',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_status_hook_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_translate_name',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_translate_name_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_type_checker',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_type_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_ht_time',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'gmt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_http_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_http_header_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_increment_counts',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_ind',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_index_of_response',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_init_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'shared_score'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_init_vhost_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_init_virtual_host',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'main_server'
+ },
+ {
+ 'type' => 'server_rec **',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_internal_fast_redirect',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'sub_req'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_internal_redirect',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_internal_redirect_handler',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_invoke_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_directory',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_initial_req',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_matchexp',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_rdirectory',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_recursion_limit_exceeded',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_url',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'u'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_limit_section',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_lingering_close',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_listen_pre_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_location_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_assert',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szExp'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szFile'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nLine'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_error',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg6'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_perror',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg6'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_rerror',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg6'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_lookup_provider',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_make_content_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_dirstr_parent',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_dirstr_prefix',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_etag',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'force_weak'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_full_path',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_method_list_t *',
+ 'name' => 'ap_make_method_list',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_matches_request_vhost',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'host'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5_binary',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5contextTo64',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5digest',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'infile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_meets_conditions',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t*',
+ 'name' => 'ap_merge_per_dir_configs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'new_conf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_in_list',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_is_limited',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_list_add',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_list_do',
+ 'args' => [
+ {
+ 'type' => 'int (*comp) (void *urec, const char *mname, int mnum)',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const ap_method_list_t *',
+ 'name' => 'ml'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_list_remove',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_list_vdo',
+ 'args' => [
+ {
+ 'type' => 'int (*comp) (void *urec, const char *mname, int mnum)',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const ap_method_list_t *',
+ 'name' => 'ml'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'vp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_method_name_of',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'methnum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_number_of',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_register',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'methname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_registry_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_check',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_close',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_mpm_pod_killpg',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_open',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_pod_t **',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_signal',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_query',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'query_code'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'result'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_mpm_rewrite_args',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_mpm_run',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server_conf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_accept_lock_mech',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_coredumpdir',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_lockfile',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_max_mem_free',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_max_requests',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_pidfile',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_no2slash',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_note_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_note_basic_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_note_digest_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_old_write_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_open_logs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's_main'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'piped_log *',
+ 'name' => 'ap_open_piped_log',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'program'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_open_stderr_log',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_os_create_privileged_process',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'newproc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'progname'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'env'
+ },
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_os_escape_path',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'partial'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_os_is_path_absolute',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_parse_htaccess',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t **',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'access_name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_parse_uri',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_parse_vhost_addrs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pass_brigade',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_pbase64decode',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'bufcoded'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_pbase64encode',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_configfile_t *',
+ 'name' => 'ap_pcfg_open_custom',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'descr'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'int(*getc_func)(void*)',
+ 'name' => 'arg3'
+ },
+ {
+ 'type' => 'void *(*gets_func) (void *buf, size_t bufsiz, void *param)',
+ 'name' => 'arg4'
+ },
+ {
+ 'type' => 'int(*close_func)(void *param)',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pcfg_openfile',
+ 'args' => [
+ {
+ 'type' => 'ap_configfile_t **',
+ 'name' => 'ret_cfg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'ap_pcw_srv_cb_t',
+ 'name' => 'srv_cb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_default_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_directory_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'core_server_config *',
+ 'name' => 'sconf'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_files_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'core_dir_config *',
+ 'name' => 'dconf'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_location_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'core_server_config *',
+ 'name' => 'sconf'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_server_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_srv_cb_t',
+ 'name' => 'srv_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'regex_t *',
+ 'name' => 'ap_pregcomp',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cflags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pregfree',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'regex_t *',
+ 'name' => 'reg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_pregsub',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'regmatch_t',
+ 'name' => 'pmatch'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_process_child_status',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'apr_exit_why_e',
+ 'name' => 'why'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_config_tree',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_process_request_internal',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_resource_config',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_psignature',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'prefix'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'ap_rationalize_mtime',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'server_rec *',
+ 'name' => 'ap_read_config',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'config_name'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_read_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'pid_t *',
+ 'name' => 'mypid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_read_request',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_recent_ctime',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_recent_rfc822_date',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_reclaim_child_processes',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'terminate'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'size_t',
+ 'name' => 'ap_regerror',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'errcode'
+ },
+ {
+ 'type' => 'const regex_t *',
+ 'name' => 'preg'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'errbuf'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'errbuf_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_regexec',
+ 'args' => [
+ {
+ 'type' => 'regex_t *',
+ 'name' => 'preg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'regmatch_t',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'eflags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_extra_mpm_process',
+ 'args' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_hooks',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_register_input_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_in_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_register_output_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_out_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_register_provider',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'provider'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_register_request_note',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_input_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_loaded_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_output_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_reopen_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'shm'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'detached'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_replace_stderr_log',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const apr_array_header_t *',
+ 'name' => 'ap_requires',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_resolve_env',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'word'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_response_code_string',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'error_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_rfc1413',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'conn'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'srv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rflush',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_rgetline_core',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'read'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'fold'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rind',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rprintf',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rputc',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rputs',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_access_checker',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_auth_checker',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_check_user_id',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pchild'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'conn_rec *',
+ 'name' => 'ap_run_create_connection',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'csd'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'conn_id'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'alloc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_create_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'ap_run_default_port',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_error_log',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'errstr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_fixups',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_get_mgmt_items',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_unix_identity_t *',
+ 'name' => 'ap_run_get_suexec_identity',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_header_parser',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_run_http_method',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_insert_error_filter',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_insert_filter',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_log_transaction',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_map_to_storage',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_open_logs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_optional_fn_retrieve',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_post_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_post_read_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_pre_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_pre_mpm',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_scoreboard_e',
+ 'name' => 'sb_type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_process_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_quick_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'lookup_uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_rewrite_args',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_status_hook',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_sub_req',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_translate_name',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_type_checker',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rvputs',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rwrite',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_satisfies',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_save_brigade',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade **',
+ 'name' => 'save_to'
+ },
+ {
+ 'type' => 'apr_bucket_brigade **',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_send_error_response',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'recursive_error'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_send_fd',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_send_http_options',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_send_http_trace',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'size_t',
+ 'name' => 'ap_send_mmap',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_server_root_relative',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_set_config_vectors',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'section_vector'
+ },
+ {
+ 'type' => 'const char *section',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_content_length',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_content_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ct'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_deprecated',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_etag',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_file_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_flag_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_int_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_set_keepalive',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_last_modified',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_listenbacklog',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_listener',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ips'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'const module *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_name_virtual_host',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_send_buffer_size',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_string_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_string_slot_lower',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_sub_req_protocol',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'rnew'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_setup_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_policy'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_setup_listeners',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_setup_make_content_type',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_setup_prelinked_modules',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_should_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_show_directives',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_show_modules',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_show_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_signal_server',
+ 'args' => [
+ {
+ 'type' => 'int *',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_single_module_configure',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_size_list_item',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'field'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_soak_end_container',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'directive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_some_auth_required',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_str_tolower',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_strcasecmp_match',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'expected'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strcasestr',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strchr',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_strchr_c',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_strcmp_match',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'expected'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_stripprefix',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'bigstring'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'prefix'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strrchr',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_strrchr_c',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strstr',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_strstr_c',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_lookup_dirent',
+ 'args' => [
+ {
+ 'type' => 'const apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'subtype'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_lookup_file',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_lookup_uri',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_method_uri',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_sub_req_output_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_time_process_request',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'uid_t',
+ 'name' => 'ap_uname2id',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unescape_url',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unescape_url_keep2f',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unregister_extra_mpm_process',
+ 'args' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_update_child_status',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_update_child_status_from_indexes',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'child_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'thread_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_update_mtime',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'dependency_mtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_update_vhost_from_headers',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_update_vhost_given_ip',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'conn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_vrprintf',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'vlist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_wait_or_timeout',
+ 'args' => [
+ {
+ 'type' => 'apr_exit_why_e *',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'exitcode'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'ret'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_walk_config',
+ 'args' => [
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'section_vector'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_xml_parse_input',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_xml_doc **',
+ 'name' => 'pdoc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_accept',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'new_sock'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'connection_pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_memnode_t *',
+ 'name' => 'apr_allocator_alloc',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_allocator_create',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t **',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_free',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_memnode_t *',
+ 'name' => 'memnode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_thread_mutex_t *',
+ 'name' => 'apr_allocator_get_mutex',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_allocator_get_owner',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_max_free_set',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_thread_mutex_t *',
+ 'name' => 'apr_allocator_mutex_get',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_mutex_set',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_allocator_owner_get',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_owner_set',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_set_max_free',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_set_mutex',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_set_owner',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_app_initialize',
+ 'args' => [
+ {
+ 'type' => 'int *',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'char const * const * *',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'char const * const * *',
+ 'name' => 'env'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_append',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'first'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'second'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_array_cat',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'dst'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_copy_hdr',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_make',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'elt_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_array_pop',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_array_pstrcat',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'arr'
+ },
+ {
+ 'type' => 'const char',
+ 'name' => 'sep'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_array_push',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int64_t',
+ 'name' => 'apr_atoi64',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_atomic_add',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_atomic_cas',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'with'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'cmp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_atomic_dec',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_atomic_inc',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_atomic_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_atomic_set',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_decode',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'plain_dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'coded_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_decode_binary',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'plain_dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'coded_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_decode_len',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'coded_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_encode',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'coded_dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'plain_src'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len_plain_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_encode_binary',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'coded_dst'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'plain_src'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len_plain_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_encode_len',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bind',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_brigade *',
+ 'name' => 'apr_brigade_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_flatten',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_length',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_all'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_partition',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'point'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'after_point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_pflatten',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_printf',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg4'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_putc',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_puts',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_putstrs',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_brigade *',
+ 'name' => 'apr_brigade_split',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'e'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_split_line',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bbOut'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bbIn'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'maxbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_to_iovec',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nvec'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_vprintf',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'va'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_vputstrs',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'va'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_write',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_writev',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_bucket_alloc',
+ 'args' => [
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_alloc_t *',
+ 'name' => 'apr_bucket_alloc_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_alloc_t *',
+ 'name' => 'apr_bucket_alloc_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_bucket_alloc_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_copy_notimpl',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'e'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_bucket_destroy_noop',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_eos_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_eos_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_file_create',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_file_enable_mmap',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'enabled'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_file_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_flush_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_flush_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_bucket_free',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'block'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_heap_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'void (*free_func)(void *data)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_heap_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'void (*free_func)(void *data)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_immortal_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_immortal_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_mmap_create',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_mmap_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pipe_create',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thispipe'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pipe_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thispipe'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pool_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pool_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_setaside_noop',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_setaside_notimpl',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_shared_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_bucket_shared_destroy',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_shared_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_shared_split',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_simple_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_simple_split',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_socket_create',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thissock'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_socket_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thissock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_split_notimpl',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_transient_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_transient_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_collapse_spaces',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dest'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_connect',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_cpystrn',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'src'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'dst_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ctime',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_current_userid',
+ 'args' => [
+ {
+ 'type' => 'apr_uid_t *',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_date_checkmask',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'mask'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'apr_date_parse_http',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'date'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'apr_date_parse_rfc',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'date'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dbm_close',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbm_exists',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_fetch',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_datum_t *',
+ 'name' => 'pvalue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_firstkey',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t *',
+ 'name' => 'pkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dbm_freedatum',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dbm_get_usednames',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used1'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_get_usednames_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used1'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_dbm_geterror',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'errcode'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'errbuf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'errbufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_nextkey',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t *',
+ 'name' => 'pkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_open',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t **',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_open_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t **',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_store',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'value'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_close',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'thedir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_make',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_make_recursive',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_open',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t **',
+ 'name' => 'new_dir'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dirname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_read',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'thedir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_remove',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_rewind',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'thedir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_dso_error',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'dso'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dso_load',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t **',
+ 'name' => 'res_handle'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dso_sym',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_sym_t *',
+ 'name' => 'ressym'
+ },
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'symname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dso_unload',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dynamic_fn_register',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'apr_opt_fn_t *',
+ 'name' => 'pfn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_opt_fn_t *',
+ 'name' => 'apr_dynamic_fn_retrieve',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_env_delete',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'envvar'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_env_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'envvar'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_env_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'envvar'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_explode_localtime',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_explode_time',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'offs'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_append',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_attrs_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_fileattrs_t',
+ 'name' => 'attributes'
+ },
+ {
+ 'type' => 'apr_fileattrs_t',
+ 'name' => 'attr_mask'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_close',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_copy',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_data_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_dup',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'old_file'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_dup2',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'old_file'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_eof',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int32_t',
+ 'name' => 'apr_file_flags_get',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_flush',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_getc',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_gets',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_info_get',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_inherit_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_inherit_unset',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_mktemp',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'fp'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'templ'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_mtime_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_name_get',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'new_path'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_namedpipe_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'newf'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flag'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_stderr',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_stdin',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_stdout',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_perms_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_create',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_timeout_get',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thepipe'
+ },
+ {
+ 'type' => 'apr_interval_time_t *',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thepipe'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_file_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_file_printf',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_putc',
+ 'args' => [
+ {
+ 'type' => 'char',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_puts',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_read',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_read_full',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbytes'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'bytes_read'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_remove',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_rename',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_seek',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_seek_where_t',
+ 'name' => 'where'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_file_set_inherit',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_setaside',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'old_file'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_trunc',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fp'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_ungetc',
+ 'args' => [
+ {
+ 'type' => 'char',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_file_unset_inherit',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_write',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_write_full',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbytes'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'bytes_written'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_writev',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_filename_of_pathname',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_encoding',
+ 'args' => [
+ {
+ 'type' => 'int *',
+ 'name' => 'style'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_list_merge',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'liststr'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'pathelts'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_list_split',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t **',
+ 'name' => 'pathelts'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'liststr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_merge',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'newpath'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'rootpath'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'addpath'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_filepath_name_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_root',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'rootpath'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'filepath'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_fnmatch',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'strings'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_fnmatch_test',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_generate_random_bytes',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_get_groupid',
+ 'args' => [
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_get_groupname',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_get_home_directory',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'dirname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_get_userid',
+ 'args' => [
+ {
+ 'type' => 'apr_uid_t *',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_get_username',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_gethostname',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getnameinfo',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getopt',
+ 'args' => [
+ {
+ 'type' => 'apr_getopt_t *',
+ 'name' => 'os'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'opts'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'option_ch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'option_arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getopt_init',
+ 'args' => [
+ {
+ 'type' => 'apr_getopt_t **',
+ 'name' => 'os'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'argv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getopt_long',
+ 'args' => [
+ {
+ 'type' => 'apr_getopt_t *',
+ 'name' => 'os'
+ },
+ {
+ 'type' => 'const apr_getopt_option_t *',
+ 'name' => 'opts'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'option_ch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'option_arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getservbyname',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'servname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getsocketopt',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_gid_get',
+ 'args' => [
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_gid_name_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'name' => 'mech'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_global_mutex_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_global_mutex_t *',
+ 'name' => 'theglobal_mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_trylock',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_group_name_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'h'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned int',
+ 'name' => 'apr_hash_count',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_index_t *',
+ 'name' => 'apr_hash_first',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_hash_get',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t',
+ 'name' => 'klen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_make',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'h1'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'h2'
+ },
+ {
+ 'type' => 'void * (*merger)(apr_pool_t *p, const void *key, apr_ssize_t klen, const void *h1_val, const void *h2_val, const void *data)',
+ 'name' => 'arg3'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_index_t *',
+ 'name' => 'apr_hash_next',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_index_t *',
+ 'name' => 'hi'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_overlay',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'overlay'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_hash_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'thehash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hash_set',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t',
+ 'name' => 'klen'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hash_this',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_index_t *',
+ 'name' => 'hi'
+ },
+ {
+ 'type' => 'const void **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t *',
+ 'name' => 'klen'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_debug_show',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_deregister_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_sort_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_sort_register',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szHookName'
+ },
+ {
+ 'type' => 'apr_array_header_t **',
+ 'name' => 'aHooks'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_implode_gmt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_initialize',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ipsubnet_create',
+ 'args' => [
+ {
+ 'type' => 'apr_ipsubnet_t **',
+ 'name' => 'ipsub'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ipstr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'mask_or_numbits'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ipsubnet_test',
+ 'args' => [
+ {
+ 'type' => 'apr_ipsubnet_t *',
+ 'name' => 'ipsub'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_is_empty_array',
+ 'args' => [
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_is_empty_table',
+ 'args' => [
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_is_fnmatch',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_itoa',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_listen',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'backlog'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_lstat',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_ltoa',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_final',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_init',
+ 'args' => [
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_set_xlate',
+ 'args' => [
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_update',
+ 'args' => [
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_encode',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'password'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'salt'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_final',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_init',
+ 'args' => [
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_set_xlate',
+ 'args' => [
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_update',
+ 'args' => [
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_create',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t **',
+ 'name' => 'newmmap'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flag'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_dup',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t **',
+ 'name' => 'new_mmap'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'old_mmap'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'transfer_ownership'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_offset',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_off_t_toa',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_optional_hook_add',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'void (*pfn)(void)',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_optional_hook_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_os_default_encoding',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dir_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_dir_t **',
+ 'name' => 'thedir'
+ },
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dir_put',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t **',
+ 'name' => 'dir'
+ },
+ {
+ 'type' => 'apr_os_dir_t *',
+ 'name' => 'thedir'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dso_handle_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_dso_handle_t *',
+ 'name' => 'dso'
+ },
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'aprdso'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dso_handle_put',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t **',
+ 'name' => 'dso'
+ },
+ {
+ 'type' => 'apr_os_dso_handle_t',
+ 'name' => 'thedso'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_exp_time_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_exp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'aprtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_exp_time_put',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'aprtime'
+ },
+ {
+ 'type' => 'apr_os_exp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_file_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_file_put',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_global_mutex_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_global_mutex_t *',
+ 'name' => 'ospmutex'
+ },
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'pmutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_imp_time_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_imp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'aprtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_imp_time_put',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'aprtime'
+ },
+ {
+ 'type' => 'apr_os_imp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_os_locale_encoding',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_pipe_put',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_pipe_put_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'register_cleanup'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_proc_mutex_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_proc_mutex_t *',
+ 'name' => 'ospmutex'
+ },
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'pmutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_proc_mutex_put',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'pmutex'
+ },
+ {
+ 'type' => 'apr_os_proc_mutex_t *',
+ 'name' => 'ospmutex'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_shm_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_shm_t *',
+ 'name' => 'osshm'
+ },
+ {
+ 'type' => 'apr_shm_t *',
+ 'name' => 'shm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_shm_put',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'shm'
+ },
+ {
+ 'type' => 'apr_os_shm_t *',
+ 'name' => 'osshm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_sock_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_sock_t *',
+ 'name' => 'thesock'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_sock_make',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'apr_sock'
+ },
+ {
+ 'type' => 'apr_os_sock_info_t *',
+ 'name' => 'os_sock_info'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_sock_put',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_os_sock_t *',
+ 'name' => 'thesock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_os_thread_t',
+ 'name' => 'apr_os_thread_current',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_os_thread_equal',
+ 'args' => [
+ {
+ 'type' => 'apr_os_thread_t',
+ 'name' => 'tid1'
+ },
+ {
+ 'type' => 'apr_os_thread_t',
+ 'name' => 'tid2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_thread_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_thread_t **',
+ 'name' => 'thethd'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_thread_put',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t **',
+ 'name' => 'thd'
+ },
+ {
+ 'type' => 'apr_os_thread_t *',
+ 'name' => 'thethd'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_threadkey_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_threadkey_t *',
+ 'name' => 'thekey'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_threadkey_put',
+ 'args' => [
+ {
+ 'type' => 'apr_threadkey_t **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_os_threadkey_t *',
+ 'name' => 'thekey'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_palloc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_palloc_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_parse_addr_port',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'scope_id'
+ },
+ {
+ 'type' => 'apr_port_t *',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_password_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'prompt'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'pwbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_password_validate',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'passwd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_pcalloc_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_pmemdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'numsock'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'nsds'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll_revents_get',
+ 'args' => [
+ {
+ 'type' => 'apr_int16_t *',
+ 'name' => 'event'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll_setup',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t **',
+ 'name' => 'new_poll'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'num'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll_socket_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'event'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll_socket_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'events'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll_socket_mask',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'events'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll_socket_remove',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'const apr_pollfd_t *',
+ 'name' => 'descriptor'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t **',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'num'
+ },
+ {
+ 'type' => 'const apr_pollfd_t **',
+ 'name' => 'descriptors'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_remove',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'const apr_pollfd_t *',
+ 'name' => 'descriptor'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_abortfunc_t',
+ 'name' => 'apr_pool_abort_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_abort_set',
+ 'args' => [
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abortfunc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_allocator_t *',
+ 'name' => 'apr_pool_allocator_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_child_cleanup_set',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*plain_cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_status_t (*child_cleanup)(void *)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_cleanup_for_exec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_cleanup_kill',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_cleanup_null',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_cleanup_register',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*plain_cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_status_t (*child_cleanup)(void *)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_cleanup_run',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_clear_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_ex_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_destroy_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_abortfunc_t',
+ 'name' => 'apr_pool_get_abort',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_pool_get_parent',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_initialize',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_pool_is_ancestor',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_note_subprocess',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'apr_kill_conditions_e',
+ 'name' => 'how'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_pool_parent_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_set_abort',
+ 'args' => [
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abortfunc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_tag',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tag'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_terminate',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_userdata_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_userdata_set',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_userdata_setn',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_create',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'new_proc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'progname'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'env'
+ },
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_detach',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'daemonize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_fork',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_kill',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'sig'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'name' => 'mech'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_proc_mutex_defname',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_proc_mutex_lockfile',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_proc_mutex_name',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_proc_mutex_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_proc_mutex_t *',
+ 'name' => 'theproc_mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_trylock',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_other_child_alert',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reason'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_check',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_other_child_read',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_refresh',
+ 'args' => [
+ {
+ 'type' => 'apr_other_child_rec_t *',
+ 'name' => 'ocr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reason'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_refresh_all',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'reason'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_register',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'void (*maintenance) (int reason, void *, int status)',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'write_fd'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_unregister',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_wait',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'exitcode'
+ },
+ {
+ 'type' => 'apr_exit_why_e *',
+ 'name' => 'exitwhy'
+ },
+ {
+ 'type' => 'apr_wait_how_e',
+ 'name' => 'waithow'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_wait_all_procs',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'exitcode'
+ },
+ {
+ 'type' => 'apr_exit_why_e *',
+ 'name' => 'exitwhy'
+ },
+ {
+ 'type' => 'apr_wait_how_e',
+ 'name' => 'waithow'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_err_set',
+ 'args' => [
+ {
+ 'type' => 'struct apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'child_err'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'parent_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_errfn_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_child_errfn_t *',
+ 'name' => 'errfn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_in_set',
+ 'args' => [
+ {
+ 'type' => 'struct apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'child_in'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'parent_in'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_out_set',
+ 'args' => [
+ {
+ 'type' => 'struct apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'child_out'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'parent_out'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_cmdtype_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_cmdtype_e',
+ 'name' => 'cmd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_create',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t **',
+ 'name' => 'new_attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_detach_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'detach'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_dir_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_error_check_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'chk'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_io_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_limit_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'what'
+ },
+ {
+ 'type' => 'struct rlimit *',
+ 'name' => 'limit'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_psprintf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrcat',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrcatv',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrmemdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrndup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pvsprintf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'ap'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_create',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t **',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'queue_capacity'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_interrupt_all',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_pop',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_push',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned int',
+ 'name' => 'apr_queue_size',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_term',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_trypop',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_trypush',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_recv',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_recvfrom',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'from'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_register_optional_fn',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'apr_opt_fn_t *',
+ 'name' => 'pfn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_acquire',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'resource'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_create',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t **',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'min'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'smax'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'hmax'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'ttl'
+ },
+ {
+ 'type' => 'apr_reslist_constructor',
+ 'name' => 'con'
+ },
+ {
+ 'type' => 'apr_reslist_destructor',
+ 'name' => 'de'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'params'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_release',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'resource'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_opt_fn_t *',
+ 'name' => 'apr_retrieve_optional_fn',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rfc822_date',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_close',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'const apr_sdbm_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_fetch',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t *',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_firstkey',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_nextkey',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_open',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t **',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_sdbm_rdonly',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_store',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'opt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_send',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sendfile',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_hdtr_t *',
+ 'name' => 'hdtr'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sendto',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'where'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sendv',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_setsocketopt',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_setup_signal_thread',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_base64',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'clear'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'out'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_final',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_init',
+ 'args' => [
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_update',
+ 'args' => [
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_update_binary',
+ 'args' => [
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_attach',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_shm_baseaddr_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_create',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'reqsize'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_detach',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_shm_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_shm_t *',
+ 'name' => 'theshm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_shm_size_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_show_hook',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shutdown',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ },
+ {
+ 'type' => 'apr_shutdown_how_e',
+ 'name' => 'how'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_sigfunc_t *',
+ 'name' => 'apr_signal',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signo'
+ },
+ {
+ 'type' => 'apr_sigfunc_t * func',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_signal_description_get',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_signal_get_description',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_signal_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pglobal'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_signal_thread',
+ 'args' => [
+ {
+ 'type' => 'int(*signal_handler)(int signum)',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sleep',
+ 'args' => [
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_snprintf',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_sockaddr_equal',
+ 'args' => [
+ {
+ 'type' => 'const apr_sockaddr_t *',
+ 'name' => 'addr1'
+ },
+ {
+ 'type' => 'const apr_sockaddr_t *',
+ 'name' => 'addr2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_info_get',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t **',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_ip_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_ip_set',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'addr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_port_get',
+ 'args' => [
+ {
+ 'type' => 'apr_port_t *',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_port_set',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_accept',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'new_sock'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'connection_pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_addr_get',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t **',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'apr_interface_e',
+ 'name' => 'which'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_atmark',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'atmark'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_bind',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_close',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_connect',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_create',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'new_sock'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'new_sock'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'protocol'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_data_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void*)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_from_file',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'newsock'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_inherit_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_inherit_unset',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_listen',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'backlog'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_opt_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_opt_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_protocol_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'protocol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_recv',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_recvfrom',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'from'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_send',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_sendfile',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_hdtr_t *',
+ 'name' => 'hdtr'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_sendto',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'where'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_sendv',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_socket_set_inherit',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'skt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_shutdown',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ },
+ {
+ 'type' => 'apr_shutdown_how_e',
+ 'name' => 'how'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_timeout_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_interval_time_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_socket_unset_inherit',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'skt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sort_hooks',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_stat',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_strerror',
+ 'args' => [
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'statcode'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_strfsize',
+ 'args' => [
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_strftime',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'retsize'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'max'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'tm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const apr_strmatch_pattern *',
+ 'name' => 'apr_strmatch_precompile',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'case_sensitive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_strnatcasecmp',
+ 'args' => [
+ {
+ 'type' => 'char const *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'char const *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_strnatcmp',
+ 'args' => [
+ {
+ 'type' => 'char const *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'char const *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int64_t',
+ 'name' => 'apr_strtoi64',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'end'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_strtok',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'sep'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'last'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_add',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_addn',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_compress',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_table_do',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'comp'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const apr_array_header_t *',
+ 'name' => 'apr_table_elts',
+ 'args' => [
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_table_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_make',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_mergen',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_overlap',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_overlay',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 'overlay'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_set',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_setn',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_unset',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_table_vdo',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'comp'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'vp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_temp_dir_get',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'temp_dir'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_terminate',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_terminate2',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_text_append',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_text_header *',
+ 'name' => 'hdr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'text'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_broadcast',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t **',
+ 'name' => 'cond'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_cond_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_cond_t *',
+ 'name' => 'thethread_cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_signal',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_timedwait',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_wait',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t **',
+ 'name' => 'new_thread'
+ },
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_thread_start_t func',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thread'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_data_set',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup) (void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thread'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_detach',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_exit',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'retval'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_join',
+ 'args' => [
+ {
+ 'type' => 'apr_status_t *',
+ 'name' => 'retval'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_mutex_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_mutex_t *',
+ 'name' => 'thethread_mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_trylock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_once',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_once_t *',
+ 'name' => 'control'
+ },
+ {
+ 'type' => 'void (*func)(void)',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_once_init',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_once_t **',
+ 'name' => 'control'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_t *',
+ 'name' => 'thethread'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t **',
+ 'name' => 'rwlock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_rwlock_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_rwlock_t *',
+ 'name' => 'thethread_rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_rdlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_tryrdlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_trywrlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_wrlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_thread_yield',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_create',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t **',
+ 'name' => 'new_attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_detach_get',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_detach_set',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'threadkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_data_set',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup) (void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'threadkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_create',
+ 'args' => [
+ {
+ 'type' => 'apr_threadkey_t **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void (*dest)(void *)',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'new_mem'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_set',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'priv'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_ansi_put',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_time_clock_hires',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_get',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_gmt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_gmt_get',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_lt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_tz',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'offs'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'apr_time_now',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_tokenize_to_argv',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg_str'
+ },
+ {
+ 'type' => 'char ***',
+ 'name' => 'argv_out'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'token_context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_current',
+ 'args' => [
+ {
+ 'type' => 'apr_uid_t *',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_get',
+ 'args' => [
+ {
+ 'type' => 'apr_uid_t *',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_homepath_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'dirname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_name_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'apr_uri_default_port_for_scheme',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'scheme_str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_uri_parse',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_uri_parse_hostinfo',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostinfo'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'apr_uri_port_of_scheme',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'scheme_str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_uri_unparse',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_uri_t *',
+ 'name' => 'uptr'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_uuid_format',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'const apr_uuid_t *',
+ 'name' => 'uuid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_uuid_get',
+ 'args' => [
+ {
+ 'type' => 'apr_uuid_t *',
+ 'name' => 'uuid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uuid_parse',
+ 'args' => [
+ {
+ 'type' => 'apr_uuid_t *',
+ 'name' => 'uuid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uuid_str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_version',
+ 'args' => [
+ {
+ 'type' => 'apr_version_t *',
+ 'name' => 'pvsn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_version_string',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_vformatter',
+ 'args' => [
+ {
+ 'type' => 'int (*flush_func)(apr_vformatter_buff_t *b)',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'apr_vformatter_buff_t *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'ap'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_vsnprintf',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'ap'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_wait_for_io_or_timeout',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'for_read'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_close',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_conv_buffer',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'inbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'inbytes_left'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'outbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'outbytes_left'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int32_t',
+ 'name' => 'apr_xlate_conv_byte',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'inchar'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_get_sb',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'onoff'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_open',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t **',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'topage'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'frompage'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_sb_get',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'onoff'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_xml_empty_elem',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_xml_elem *',
+ 'name' => 'elem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_xml_insert_uri',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'uri_array'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xml_parse_file',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_xml_parser **',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'apr_xml_doc **',
+ 'name' => 'ppdoc'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'xmlfd'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'buffer_length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_xml_parser *',
+ 'name' => 'apr_xml_parser_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xml_parser_done',
+ 'args' => [
+ {
+ 'type' => 'apr_xml_parser *',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'apr_xml_doc **',
+ 'name' => 'pdoc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xml_parser_feed',
+ 'args' => [
+ {
+ 'type' => 'apr_xml_parser *',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_xml_parser_geterror',
+ 'args' => [
+ {
+ 'type' => 'apr_xml_parser *',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'errbuf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'errbufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_xml_quote_elem',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'elem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_xml_quote_string',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'quotes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_xml_to_text',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_xml_elem *',
+ 'name' => 'elem'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'style'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'namespaces'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'ns_map'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'pbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'psize'
+ }
+ ]
+ }
+];
+
+
+1;
diff --git a/2_0_13/xs/tables/current/Apache2/StructureTable.pm b/2_0_13/xs/tables/current/Apache2/StructureTable.pm
new file mode 100644
index 0000000..80dd06c
--- /dev/null
+++ b/2_0_13/xs/tables/current/Apache2/StructureTable.pm
@@ -0,0 +1,3461 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package Apache2::StructureTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by Apache::ParseSource/0.02
+# ! Fri Dec 10 14:14:10 2004
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$Apache2::StructureTable = [
+ {
+ 'type' => 'ap_HOOK_access_checker_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_auth_checker_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_check_user_id_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_child_init_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_create_connection_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_create_request_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_default_port_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_error_log_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_fixups_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_get_mgmt_items_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_get_suexec_identity_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_handler_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_header_parser_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_http_method_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_insert_error_filter_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_insert_filter_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_log_transaction_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_map_to_storage_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_open_logs_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_optional_fn_retrieve_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_post_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_post_read_request_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_connection_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_mpm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_process_connection_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_quick_handler_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_status_hook_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_translate_name_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_type_checker_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_LINK_access_checker_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_auth_checker_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_auth_checker_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_check_user_id_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_check_user_id_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_child_init_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_child_init_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_create_connection_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_create_connection_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_create_request_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_create_request_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_default_port_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_default_port_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_error_log_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_error_log_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_fixups_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_fixups_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_get_mgmt_items_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_get_mgmt_items_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_get_suexec_identity_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_get_suexec_identity_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_handler_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_handler_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_header_parser_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_header_parser_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_http_method_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_http_method_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_insert_error_filter_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_insert_error_filter_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_insert_filter_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_insert_filter_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_log_transaction_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_log_transaction_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_map_to_storage_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_map_to_storage_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_open_logs_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_open_logs_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_optional_fn_retrieve_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_optional_fn_retrieve_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_post_config_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_post_config_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_post_read_request_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_post_read_request_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_config_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_config_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_connection_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_connection_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_mpm_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_mpm_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_process_connection_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_process_connection_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_quick_handler_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_quick_handler_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_status_hook_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_status_hook_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_translate_name_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_translate_name_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_type_checker_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_type_checker_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_bucket_error',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_conf_vector_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_configfile_t',
+ 'elts' => [
+ {
+ 'type' => 'int(*) (void *param)',
+ 'name' => 'getch'
+ },
+ {
+ 'type' => 'void *(*) (void *buf, size_t bufsiz, void *param)',
+ 'name' => 'getstr'
+ },
+ {
+ 'type' => 'int(*) (void *param)',
+ 'name' => 'close'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'line_number'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_conn_keepalive_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_directive_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'directive'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'first_child'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line_num'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_func',
+ 'elts' => [
+ {
+ 'type' => 'ap_out_filter_func',
+ 'name' => 'out_func'
+ },
+ {
+ 'type' => 'ap_in_filter_func',
+ 'name' => 'in_func'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_rec_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init_func'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ },
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'frec'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_generation_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_in_filter_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_listen_rec',
+ 'elts' => [
+ {
+ 'type' => 'ap_listen_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sd'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'bind_addr'
+ },
+ {
+ 'type' => 'accept_function',
+ 'name' => 'accept_func'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'active'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_method_list_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_int64_t',
+ 'name' => 'method_mask'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'method_list'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_mgmt_item_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'description'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_mgmt_type_e',
+ 'name' => 'vtype'
+ },
+ {
+ 'type' => 'ap_mgmt_value',
+ 'name' => 'v'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_mgmt_type_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_mgmt_value',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's_value'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'i_value'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'h_value'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_out_filter_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_pcw_srv_cb_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_pod_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'pod_in'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'pod_out'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_sb_handle_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_scoreboard_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_unix_identity_t',
+ 'elts' => [
+ {
+ 'type' => 'uid_t',
+ 'name' => 'uid'
+ },
+ {
+ 'type' => 'gid_t',
+ 'name' => 'gid'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'userdir'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_OFN_ap_logio_add_bytes_out_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_signal_server_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_modperl_interp_unselect_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_allocator_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_array_header_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'elt_size'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nalloc'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'elts'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_bucket',
+ 'elts' => [
+ {
+ 'type' => '_ANON 53',
+ 'name' => 'link'
+ },
+ {
+ 'type' => 'const apr_bucket_type_t *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'void(*)(void *e)',
+ 'name' => 'free'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_bucket_brigade',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_list',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'bucket_alloc'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_file',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'readpool'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'can_mmap'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_heap',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'alloc_len'
+ },
+ {
+ 'type' => 'void(*)(void *data)',
+ 'name' => 'free_func'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_mmap',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mmap'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_pool',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_heap',
+ 'name' => 'heap'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'refcount'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_structs',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_bucket_type_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_func'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'is_metadata'
+ },
+ {
+ 'type' => 'void(*)(void *data)',
+ 'name' => 'destroy'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *b, const char **str, apr_size_t *len,
+ apr_read_type_e block)',
+ 'name' => 'read'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *e, apr_pool_t *pool)',
+ 'name' => 'setaside'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *e, apr_size_t point)',
+ 'name' => 'split'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *e, apr_bucket **c)',
+ 'name' => 'copy'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_byte_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_child_errfn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_cmdtype_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_datatype_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dptr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'dsize'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_dbm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_descriptor',
+ 'elts' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_dev_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dir_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dso_handle_sym_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dso_handle_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_exit_why_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_file_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_fileattrs_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_filetype_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_finfo_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'valid'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'protection'
+ },
+ {
+ 'type' => 'apr_filetype_e',
+ 'name' => 'filetype'
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'name' => 'user'
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'name' => 'group'
+ },
+ {
+ 'type' => 'apr_ino_t',
+ 'name' => 'inode'
+ },
+ {
+ 'type' => 'apr_dev_t',
+ 'name' => 'device'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'nlink'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'csize'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'atime'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'ctime'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'filehand'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_getopt_err_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_getopt_option_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'optch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'has_arg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'description'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_getopt_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ },
+ {
+ 'type' => 'apr_getopt_err_fn_t *',
+ 'name' => 'errfn'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'errarg'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ind'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reset'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'char const *',
+ 'name' => 'place'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'interleave'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'skip_start'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'skip_end'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_global_mutex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hash_index_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hash_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hdtr_t',
+ 'elts' => [
+ {
+ 'type' => 'iovec *',
+ 'name' => 'headers'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'numheaders'
+ },
+ {
+ 'type' => 'iovec *',
+ 'name' => 'trailers'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'numtrailers'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_in_addr_t',
+ 'elts' => [
+ {
+ 'type' => 'in_addr_t',
+ 'name' => 's_addr'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_ino_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_int64_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_interface_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_ipsubnet_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_kill_conditions_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_md4_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t[4]',
+ 'name' => 'state'
+ },
+ {
+ 'type' => 'apr_uint32_t[2]',
+ 'name' => 'count'
+ },
+ {
+ 'type' => 'unsigned char[64]',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_md5_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t[4]',
+ 'name' => 'state'
+ },
+ {
+ 'type' => 'apr_uint32_t[2]',
+ 'name' => 'count'
+ },
+ {
+ 'type' => 'unsigned char[64]',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_memnode_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_memnode_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_memnode_t **',
+ 'name' => 'ref'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'index'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'free_index'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'first_avail'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'endp'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_mmap_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'unused'
+ },
+ {
+ 'type' => '_ANON 51',
+ 'name' => 'link'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_opt_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_dir_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_dso_handle_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_exp_time_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'tm_sec'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_min'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_hour'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_mday'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_mon'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_year'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_wday'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_yday'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_isdst'
+ },
+ {
+ 'type' => 'long int',
+ 'name' => 'tm_gmtoff'
+ },
+ {
+ 'type' => '__const char *',
+ 'name' => 'tm_zone'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_file_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_global_mutex_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'proc_mutex'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'thread_mutex'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_imp_time_t',
+ 'elts' => [
+ {
+ 'type' => '__time_t',
+ 'name' => 'tv_sec'
+ },
+ {
+ 'type' => '__suseconds_t',
+ 'name' => 'tv_usec'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_proc_mutex_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'crossproc'
+ },
+ {
+ 'type' => 'pthread_mutex_t *',
+ 'name' => 'pthread_interproc'
+ },
+ {
+ 'type' => 'pthread_mutex_t *',
+ 'name' => 'intraproc'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_proc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_shm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_sock_info_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_os_sock_t *',
+ 'name' => 'os_sock'
+ },
+ {
+ 'type' => 'sockaddr *',
+ 'name' => 'local'
+ },
+ {
+ 'type' => 'sockaddr *',
+ 'name' => 'remote'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_sock_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_thread_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_threadkey_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_other_child_rec_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pollfd_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_datatype_e',
+ 'name' => 'desc_type'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'reqevents'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'rtnevents'
+ },
+ {
+ 'type' => 'apr_descriptor',
+ 'name' => 'desc'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'client_data'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_pollset_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pool_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_proc_mutex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_proc_t',
+ 'elts' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_procattr_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_queue_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_reslist_constructor',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_reslist_destructor',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_reslist_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dptr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'dsize'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_sdbm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_seek_where_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sha1_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t[5]',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'count_lo'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'count_hi'
+ },
+ {
+ 'type' => 'apr_uint32_t[16]',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'local'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_shm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_short_interval_time_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_shutdown_how_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sigfunc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_signum_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sockaddr_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'servname'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'union _ANON 1',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'apr_socklen_t',
+ 'name' => 'salen'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ipaddr_len'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'addr_str_len'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ipaddr_ptr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_socket_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_socklen_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_ssize_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_strmatch_pattern',
+ 'elts' => [
+ {
+ 'type' => 'const char *(*)(const apr_strmatch_pattern *this_pattern,
+ const char *s, apr_size_t slen)',
+ 'name' => 'compare'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_table_entry_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'key_checksum'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_table_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_text',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'text'
+ },
+ {
+ 'type' => 'apr_text *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_text_header',
+ 'elts' => [
+ {
+ 'type' => 'apr_text *',
+ 'name' => 'first'
+ },
+ {
+ 'type' => 'apr_text *',
+ 'name' => 'last'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_thread_cond_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_mutex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_once_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_rwlock_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_start_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_threadattr_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_threadkey_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_time_exp_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_usec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_sec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_min'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_hour'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_mday'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_mon'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_year'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_wday'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_yday'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_isdst'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_gmtoff'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uint64_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uri_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'scheme'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'hostinfo'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'user'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'password'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'port_str'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'query'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'fragment'
+ },
+ {
+ 'type' => 'hostent *',
+ 'name' => 'hostent'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'is_initialized'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'dns_looked_up'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'dns_resolved'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_uuid_t',
+ 'elts' => [
+ {
+ 'type' => 'unsigned char[16]',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_version_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'major'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'minor'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'patch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'is_dev'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_vformatter_buff_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'curpos'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'endpos'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_wait_how_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_xlate_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_xml_attr',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ns'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'apr_xml_attr *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_xml_doc',
+ 'elts' => [
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'root'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'namespaces'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_xml_elem',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ns'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'lang'
+ },
+ {
+ 'type' => 'apr_text_header',
+ 'name' => 'first_cdata'
+ },
+ {
+ 'type' => 'apr_text_header',
+ 'name' => 'following_cdata'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'first_child'
+ },
+ {
+ 'type' => 'apr_xml_attr *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'last_child'
+ },
+ {
+ 'type' => 'apr_xml_ns_scope *',
+ 'name' => 'ns_scope'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'priv'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_xml_parser',
+ 'elts' => []
+ },
+ {
+ 'type' => 'cmd_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'cmd_parms',
+ 'elts' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'info'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'apr_int64_t',
+ 'name' => 'limited'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'limited_xmethods'
+ },
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'xlimited'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'config_file'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'directive'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'const command_rec *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const ap_directive_t *',
+ 'name' => 'err_directive'
+ }
+ ]
+ },
+ {
+ 'type' => 'command_rec',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'cmd_func',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'cmd_data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'req_override'
+ },
+ {
+ 'type' => 'enum cmd_how',
+ 'name' => 'args_how'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'errmsg'
+ }
+ ]
+ },
+ {
+ 'type' => 'conn_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'vhost_lookup_data'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'local_addr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'remote_addr'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'remote_ip'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'remote_host'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'remote_logname'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'aborted'
+ },
+ {
+ 'type' => 'ap_conn_keepalive_e',
+ 'name' => 'keepalive'
+ },
+ {
+ 'type' => 'signed int',
+ 'name' => 'double_reverse'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'keepalives'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'local_ip'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'local_host'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'id'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'conn_config'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'notes'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'input_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'output_filters'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'bucket_alloc'
+ }
+ ]
+ },
+ {
+ 'type' => 'core_net_rec',
+ 'elts' => []
+ },
+ {
+ 'type' => 'htaccess_result',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'htaccess'
+ },
+ {
+ 'type' => 'const struct htaccess_result *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_uri_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uri_t',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path_info'
+ }
+ ]
+ },
+ {
+ 'type' => 'module',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'version'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'minor_version'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dynamic_load_handle'
+ },
+ {
+ 'type' => 'module_struct *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'unsigned long',
+ 'name' => 'magic'
+ },
+ {
+ 'type' => 'void(*) (process_rec *process)',
+ 'name' => 'rewrite_args'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, char *dir)',
+ 'name' => 'create_dir_config'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, void *base_conf, void *new_conf)',
+ 'name' => 'merge_dir_config'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, server_rec *s)',
+ 'name' => 'create_server_config'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, void *base_conf,
+ void *new_conf)',
+ 'name' => 'merge_server_config'
+ },
+ {
+ 'type' => 'const command_rec *',
+ 'name' => 'cmds'
+ },
+ {
+ 'type' => 'void(*) (apr_pool_t *p)',
+ 'name' => 'register_hooks'
+ }
+ ]
+ },
+ {
+ 'type' => 'piped_log',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_file_t *[2]',
+ 'name' => 'fds'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'program'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'pid'
+ }
+ ]
+ },
+ {
+ 'type' => 'process_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'short_name'
+ }
+ ]
+ },
+ {
+ 'type' => 'request_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'connection'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'prev'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'main'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'the_request'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'assbackwards'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'proxyreq'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'header_only'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'protocol'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'proto_num'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'request_time'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'status_line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'method_number'
+ },
+ {
+ 'type' => 'apr_int64_t',
+ 'name' => 'allowed'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'allowed_xmethods'
+ },
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'allowed_methods'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'sent_bodyct'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'bytes_sent'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'chunked'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'range'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'clength'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'remaining'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'read_length'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_body'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_chunked'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'expecting_100'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'headers_in'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'headers_out'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'err_headers_out'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'subprocess_env'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'notes'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'content_type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'content_encoding'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'content_languages'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'vlist_validator'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'user'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'ap_auth_type'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'no_cache'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'no_local_copy'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'unparsed_uri'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'canonical_filename'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path_info'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'apr_finfo_t',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'apr_uri_t',
+ 'name' => 'parsed_uri'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'used_path_info'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'per_dir_config'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'request_config'
+ },
+ {
+ 'type' => 'const struct htaccess_result *',
+ 'name' => 'htaccess'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'output_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'input_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'proto_output_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'proto_input_filters'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'eos_sent'
+ }
+ ]
+ },
+ {
+ 'type' => 'server_addr_rec',
+ 'elts' => [
+ {
+ 'type' => 'server_addr_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'host_addr'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'host_port'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'virthost'
+ }
+ ]
+ },
+ {
+ 'type' => 'server_rec',
+ 'elts' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'defn_name'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'defn_line_number'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'server_admin'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'server_hostname'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'error_fname'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'error_log'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'loglevel'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'is_virtual'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'module_config'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'lookup_defaults'
+ },
+ {
+ 'type' => 'server_addr_rec *',
+ 'name' => 'addrs'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'keep_alive_timeout'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'keep_alive_max'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'keep_alive'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'pathlen'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'names'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'wild_names'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'limit_req_line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'limit_req_fieldsize'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'limit_req_fields'
+ }
+ ]
+ },
+ {
+ 'type' => 'subrequest_rec',
+ 'elts' => []
+ },
+ {
+ 'type' => 'unixd_config_rec',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'user_name'
+ },
+ {
+ 'type' => 'uid_t',
+ 'name' => 'user_id'
+ },
+ {
+ 'type' => 'gid_t',
+ 'name' => 'group_id'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'suexec_enabled'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_interp_t',
+ 'elts' => [
+ {
+ 'type' => 'modperl_interp_pool_t *',
+ 'name' => 'mip'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_requests'
+ },
+ {
+ 'type' => 'U8',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'modperl_config_con_t *',
+ 'name' => 'ccfg'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'refcnt'
+ },
+ {
+ 'type' => 'unsigned long',
+ 'name' => 'tid'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_interp_pool_t',
+ 'elts' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'modperl_tipool_config_t *',
+ 'name' => 'tipool_cfg'
+ },
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'parent'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_tipool_t',
+ 'elts' => [
+ {
+ 'type' => 'perl_mutex',
+ 'name' => 'tiplock'
+ },
+ {
+ 'type' => 'perl_cond',
+ 'name' => 'available'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'idle'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'busy'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'in_use'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'modperl_tipool_config_t *',
+ 'name' => 'cfg'
+ },
+ {
+ 'type' => 'modperl_tipool_vtbl_t *',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_tipool_config_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'min_spare'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'max_spare'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'max'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'max_requests'
+ }
+ ]
+ }
+];
+
+
+1;
diff --git a/2_0_13/xs/tables/current/ModPerl/FunctionTable.pm b/2_0_13/xs/tables/current/ModPerl/FunctionTable.pm
new file mode 100644
index 0000000..e5b47ce
--- /dev/null
+++ b/2_0_13/xs/tables/current/ModPerl/FunctionTable.pm
@@ -0,0 +1,8296 @@
+# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
+package ModPerl::FunctionTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by ModPerl::ParseSource/0.01
+# ! Mon May 23 14:15:47 2005
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$ModPerl::FunctionTable = [
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_access_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_apr_array_header2avrv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'array'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_authen_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_authz_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'modperl_avrv2apr_array_header',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'avrv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_brigade_dump',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'modperl_bucket_sv_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'args'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_files',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_per_dir',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_per_srv',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_callback_process',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_run_handlers',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_cgi_header_parse',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'body'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_child_init_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_cleanup_data_t *',
+ 'name' => 'modperl_cleanup_data_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_END',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_access_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_add_var',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_authen_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_authz_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_child_exit_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_child_init_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_cleanup_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_config_requires',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_fixup_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_header_parser_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_init_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_input_filter_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_max',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_max_requests',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_max_spare',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_min_spare',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_start',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_load_module',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_log_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_map_to_storage_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_modules',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_open_logs_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_options',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_output_filter_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pass_env',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_perl',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_perldo',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pod',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pod_cut',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_post_config_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_post_config_requires',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_post_read_request_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pre_connection_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_process_connection_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_cmd_push_filter_handlers',
+ 'args' => [
+ {
+ 'type' => 'MpAV **',
+ 'name' => 'handlers'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_cmd_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'MpAV **',
+ 'name' => 'handlers'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_requires',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_response_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_env',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_input_filter',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_output_filter',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_var',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_switches',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_trace',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_trans_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_type_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U16 *',
+ 'name' => 'modperl_code_attrs',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'CV *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_apply_PerlModule',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_apply_PerlPostConfigRequire',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_apply_PerlRequire',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_dir_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_dir_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'basev'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'addv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_dir_t *',
+ 'name' => 'modperl_config_dir_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptmp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_options'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'conf'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert_parms',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert_request',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert_server',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_is_perl_option_enabled',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_config_req_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_req_t *',
+ 'name' => 'modperl_config_req_new',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_con_t *',
+ 'name' => 'modperl_config_con_new',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_config_request_cleanup',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char **',
+ 'name' => 'modperl_config_srv_argv_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'argc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_srv_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_srv_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'basev'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'addv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_srv_t *',
+ 'name' => 'modperl_config_srv_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_const_compile',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char **',
+ 'name' => 'modperl_constants_group_lookup_apache2_const',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char **',
+ 'name' => 'modperl_constants_group_lookup_apr_const',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char **',
+ 'name' => 'modperl_constants_group_lookup_modperl',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_constants_lookup_apache2_const',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_constants_lookup_apr_const',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_constants_lookup_modperl',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_croak',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned long',
+ 'name' => 'modperl_debug_level',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_dir_config',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_configure_request_dir',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_configure_request_srv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_configure_server',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_default_populate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_hash_keys',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_hv_store',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_init',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_populate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_tie',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_unpopulate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_untie',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_sync_dir_env_hash2table',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_config_dir_t *',
+ 'name' => 'dcfg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_sync_srv_env_hash2table',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_unload',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_error_strerror',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_errsv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_errsv_prepend',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pat'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_file2package',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U32 *',
+ 'name' => 'modperl_filter_attributes',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cvrv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_filter_t *',
+ 'name' => 'modperl_filter_mg_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_filter_t *',
+ 'name' => 'modperl_filter_new',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'modperl_filter_mode_e',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'input_mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_filter_resolve_init_handler',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_filter_runtime_add',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'modperl_filter_mode_e',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'modperl_filter_add_t',
+ 'name' => 'addfunc'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_fixup_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U32',
+ 'name' => 'modperl_flags_lookup_dir',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U32',
+ 'name' => 'modperl_flags_lookup_srv',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_get_perl_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_anon_cnt_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_global_anon_cnt_next',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_global_get',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'modperl_global_get_pconf',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'server_rec *',
+ 'name' => 'modperl_global_get_server_rec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_init_pconf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_init_server_rec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec * server_rec',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_lock',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_lock_pconf',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_lock_server_rec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'modperl_global_request',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'svr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_request_cfg_set',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_request_obj_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'svr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_request_set',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_set',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_set_pconf',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_set_server_rec',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_unlock',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_unlock_pconf',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_unlock_server_rec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_handler_anon_add',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'anon'
+ },
+ {
+ 'type' => 'CV *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'CV *',
+ 'name' => 'modperl_handler_anon_get',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'anon'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_handler_anon_init',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_handler_anon_next',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'MpAV *',
+ 'name' => 'modperl_handler_array_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'MpAV *',
+ 'name' => 'base_a'
+ },
+ {
+ 'type' => 'MpAV *',
+ 'name' => 'add_a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_files',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_per_dir',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_per_srv',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_process',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_handler_t *',
+ 'name' => 'modperl_handler_dup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'h'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_equal',
+ 'args' => [
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'h1'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'h2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'MpAV **',
+ 'name' => 'modperl_handler_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'modperl_handler_action_e',
+ 'name' => 'action'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_lookup',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'MpAV **',
+ 'name' => 'modperl_handler_lookup_handlers',
+ 'args' => [
+ {
+ 'type' => 'modperl_config_dir_t *',
+ 'name' => 'dcfg'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'modperl_config_req_t *',
+ 'name' => 'rcfg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'modperl_handler_action_e',
+ 'name' => 'action'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'desc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_handler_make_args',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'AV **',
+ 'name' => 'avp'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_name',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_handler_t *',
+ 'name' => 'modperl_handler_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_handler_t *',
+ 'name' => 'modperl_handler_new_from_sv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_perl_add_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'modperl_handler_action_e',
+ 'name' => 'action'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_handler_perl_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'MpAV **',
+ 'name' => 'handp'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'MpAV *',
+ 'name' => 'handlers'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_resolve',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t **',
+ 'name' => 'handp'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_hash_seed_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_hash_seed_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_hash_tie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_hash_tied_object',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_hash_tied_object_rv',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_header_parser_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_hook_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_hook_pre_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_init',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_init_globals',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_init_vhost',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_input_filter_add_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_input_filter_add_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_input_filter_flush',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_input_filter_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'input_mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'modperl_input_filter_read',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'wanted'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_input_filter_write',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_clone_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_destroy',
+ 'args' => [
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_get',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_init',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_mip_walk',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'current_perl'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'parent_perl'
+ },
+ {
+ 'type' => 'modperl_interp_pool_t *',
+ 'name' => 'mip'
+ },
+ {
+ 'type' => 'modperl_interp_mip_walker_t',
+ 'name' => 'walker'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_mip_walk_servers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'current_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ },
+ {
+ 'type' => 'modperl_interp_mip_walker_t',
+ 'name' => 'walker'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_new',
+ 'args' => [
+ {
+ 'type' => 'modperl_interp_pool_t *',
+ 'name' => 'mip'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_pool_destroy',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_pool_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_pool_select',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_pool_set',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cleanup'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_select',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_unselect',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_apache_init',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_handle_tie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_io_handle_tied',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_handle_untie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_perlio_override_stdin',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_perlio_override_stdout',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_perlio_restore_stdin',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_perlio_restore_stdout',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_tie_stdin',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_tie_stdout',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_is_running',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_append',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'new_list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_first',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_last',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_new',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_prepend',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'new_list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_remove',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'rlist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_remove_data',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'modperl_list_t **',
+ 'name' => 'listp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_log_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_map_to_storage_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_mgv_append',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_mgv_as_string',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_mgv_compile',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_mgv_equal',
+ 'args' => [
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'mgv1'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'mgv2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_mgv_hash_handlers',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_mgv_last',
+ 'args' => [
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_mgv_last_name',
+ 'args' => [
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_mgv_lookup',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_mgv_lookup_autoload',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_mgv_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_mgv_require_module',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_mgv_resolve',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logfailure'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_modglobal_hash_keys',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_modglobal_key_t *',
+ 'name' => 'modperl_modglobal_lookup',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_module_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'mod_cmds'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_module_config_get_obj',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'pmodule'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'v'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PTR_TBL_t *',
+ 'name' => 'modperl_module_config_table_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'create'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_module_config_table_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'table'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_newSVsv_obj',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'stashsv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_open_logs_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_options_t *',
+ 'name' => 'modperl_options_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_options_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'modperl_options_t *new',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_options_t *',
+ 'name' => 'modperl_options_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_options_set',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_options_t *',
+ 'name' => 'o'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_output_filter_add_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_output_filter_add_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_output_filter_flush',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_output_filter_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'modperl_output_filter_read',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'wanted'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_output_filter_write',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_package_unload',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_av_push_elts_ref',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'dst'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_call_endav',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_call_list',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'subs'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_core_global_init',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_destruct',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_perl_destruct_level',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_do_join',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_do_sprintf',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sarg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_exit',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_gensym',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'pack'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_avcv_call',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_modglobal_key_t *',
+ 'name' => 'gkey'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'packlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_avcv_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_modglobal_key_t *',
+ 'name' => 'gkey'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'packlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_avcv_register',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_modglobal_key_t *',
+ 'name' => 'gkey'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'packlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_request_restore',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_request_save',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'HE *',
+ 'name' => 'modperl_perl_hv_fetch_he',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'HV *',
+ 'name' => 'hv'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'klen'
+ },
+ {
+ 'type' => 'U32',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_init_ids_server',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_perl_module_loaded',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_set',
+ 'args' => [
+ {
+ 'type' => 'modperl_perl_opcode_e',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_set_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_unset',
+ 'args' => [
+ {
+ 'type' => 'modperl_perl_opcode_e',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_unset_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_sv_setref_uv',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'rv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'UV',
+ 'name' => 'uv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_pnotes',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'HV **',
+ 'name' => 'pnotes'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_pnotes_kill',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'cl_data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_post_config_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_post_post_config_phase',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_post_read_request_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_pre_connection_handler',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_process_connection_handler',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_ptr2obj',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_register_handler_hooks',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_register_hooks',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ssize_t',
+ 'name' => 'modperl_request_read',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_require_file',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logfailure'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_require_module',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logfailure'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_response_finish',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_response_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_response_handler_cgi',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_response_init',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_restart_count',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_restart_count_inc',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_run',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_run_filter',
+ 'args' => [
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_server_desc',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'modperl_server_pool',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'modperl_server_user_pool',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_set_perl_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'cfg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_slurp_filename',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tainted'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_spawn_proc_prog',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'command'
+ },
+ {
+ 'type' => 'const char ***',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'script_in'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'script_out'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'script_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PerlInterpreter *',
+ 'name' => 'modperl_startup',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_str_toupper',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'modperl_sv2request_rec',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'server_rec *',
+ 'name' => 'modperl_sv2server_rec',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PTR_TBL_t *',
+ 'name' => 'modperl_svptr_table_clone',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'proto_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'source'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_delete',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_destroy',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_svptr_table_fetch',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_free',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PTR_TBL_t *',
+ 'name' => 'modperl_svptr_table_new',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_split',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_store',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'oldv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'newv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_sys_dlclose',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_sys_is_dir',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_table_get_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'table'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_val'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'do_taint'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_threaded_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_threads_started',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_thx_interp_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'thx',
+ },
+ ],
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_thx_interp_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'thx',
+ },
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp',
+ },
+ ],
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_add',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_destroy',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_tipool_t *',
+ 'name' => 'modperl_tipool_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_tipool_config_t *',
+ 'name' => 'cfg'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_tipool_pop',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_putback',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'listp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_requests'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_putback_data',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_requests'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_remove',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'listp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_tls_t **',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_create_request_rec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_get',
+ 'args' => [
+ {
+ 'type' => 'modperl_tls_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_get_request_rec',
+ 'args' => [
+ {
+ 'type' => 'request_rec * *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tls_reset_cleanup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_tls_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tls_reset_cleanup_request_rec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_set',
+ 'args' => [
+ {
+ 'type' => 'modperl_tls_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_set_request_rec',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_level_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'level'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_logfile_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile_new'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_trans_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_type_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_uri_t *',
+ 'name' => 'modperl_uri_new',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_wbucket_flush',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_wbucket_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'add_flush_bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_wbucket_pass',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_wbucket_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'add_flush_bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_wbucket_write',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_wbucket_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'wlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_xs_dl_handles_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_xs_dl_handles_close',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'handles'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void **',
+ 'name' => 'modperl_xs_dl_handles_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'modperl_xs_sv2request_rec',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'CV *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_cleanup',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_concat',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_destroy',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_first',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_APR__Brigade_flatten',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_insert_head',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_insert_tail',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Brigade_is_empty',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_last',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Brigade_length',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_all'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_next',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'mpxs_APR__Brigade_pool',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_prev',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__BucketAlloc_new',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Bucket_insert_after',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Bucket_insert_before',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Bucket_is_eos',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Bucket_is_flush',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Bucket_new',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_APR__Bucket_read',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Bucket_remove',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_APR__Bucket_setaside',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'b_sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Finfo_stat',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U32',
+ 'name' => 'mpxs_APR__OS_current_thread_id',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Pool_clear',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int32_t',
+ 'name' => 'mpxs_APR__Socket_opt_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Socket_opt_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_APR__Socket_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'reqevents'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_APR__Socket_recv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Socket_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Socket_fileno',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__String_strfsize',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Table_EXISTS',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_APR__Table_FETCH',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_APR__Table_NEXTKEY',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Table_copy',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Table_make',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Table_overlay',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'overlay'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_APR__URI_port',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'portsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__URI_rpath',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'apr_uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__CmdParms_add_config',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__CmdParms_info',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__CmdParms_override_opts',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Connection_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Connection_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_socket_t *',
+ 'name' => 'mpxs_Apache2__Connection_client_socket',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__Connection_get_remote_host',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'dir_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Connection_pnotes',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Connection_pnotes_kill',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Directive_as_hash',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'tree'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Directive_as_string',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'self'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Filter_ctx',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__Filter_fflush',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__Filter_get_brigade',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__Filter_pass_brigade',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_Apache2__Filter_print',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_Apache2__Filter_read',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Filter_remove',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Filter_seen_eos',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Log_BOOT',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Log_log',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logtype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__MPM_BOOT',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__MPM_query',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'self'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'query_code'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Module_add',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cmds'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__Module_ap_api_major_version',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__Module_ap_api_minor_version',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Module_get_config',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'pmodule'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'v'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__Module_loaded',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_FILENO',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_GETC',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_OPEN',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'self'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_add_config',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_allow_override_opts',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_as_string',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_auth_name',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_auth_type',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_child_terminate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_content_languages',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'languages'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_content_type',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_document_root',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'new_root'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_finfo_t *',
+ 'name' => 'mpxs_Apache2__RequestRec_finfo',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_handler',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_is_perl_option_enabled',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_Apache2__RequestRec_location',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_location_merge',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'location'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_new',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'base_pool_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_no_cache',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'flag'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uri_t *',
+ 'name' => 'mpxs_Apache2__RequestRec_parsed_uri',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_pnotes',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_pnotes_kill',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_print',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_proxyreq',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_read',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_rflush',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__RequestRec_sendfile',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_set_basic_credentials',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'password'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_set_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_Apache2__RequestRec_set_last_modified',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_subprocess_env',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_Apache2__RequestRec_write',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'mpxs_Apache2__RequestUtil_request',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'svr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__ServerRec_add_config',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__ServerRec_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_is_perl_option_enabled',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_set_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__ServerUtil_BOOT',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ModPerl__Global_special_list_call',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ModPerl__Global_special_list_clear',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ModPerl__Global_special_list_register',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_ModPerl__Util_untaint',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_ap_allow_methods',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'long',
+ 'name' => 'mpxs_ap_get_client_block',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'bufsiz'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_ap_log_error',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'msg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_ap_requires',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_ap_rprintf',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ap_run_sub_req',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_ap_rvputs',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_ap_unescape_url',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_base64_decode',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_base64_encode',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_brigade_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'ba'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_ipsubnet_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ipstr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'mask_or_numbits'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_apr_password_validate',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'passwd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_pool_DESTROY',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_apr_pool_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'cleanup_data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_pool_cleanup_register',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_pool_create',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'parent_pool_obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_apr_pool_parent_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'child_pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_apr_sockaddr_ip_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_apr_socket_send',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_buf'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_interval_time_t',
+ 'name' => 'mpxs_apr_socket_timeout_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_apr_table_do',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_apr_table_do_cb',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_thread_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_thread_rwlock_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_uri_parse',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri_string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_apr_uri_unparse',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uptr'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uuid_t *',
+ 'name' => 'mpxs_apr_uuid_get',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uuid_t *',
+ 'name' => 'mpxs_apr_uuid_parse',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_cleanup_run',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_insert_auth_cfg',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'directive'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_setup_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_special_list_do',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'mpxs_special_list_do_t',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'mpxs_ModPerl__Interpreter_current',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'class'
+ }
+ ]
+ }
+];
+
+
+1;
diff --git a/2_0_13/xs/tables/current24/APR/FunctionTable.pm b/2_0_13/xs/tables/current24/APR/FunctionTable.pm
new file mode 100644
index 0000000..cf3d278
--- /dev/null
+++ b/2_0_13/xs/tables/current24/APR/FunctionTable.pm
@@ -0,0 +1,228 @@
+package APR::FunctionTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: this file was manually generated on
+# ! Tue Jun 22 22:00:00 2004
+# ! It contains a subset of functions appearing in
+# ! ModPerl::FunctionTable used to build APR.so
+# ! Eventually this will be autogenerated by
+# ! Apache::ParseSource
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$APR::FunctionTable = [
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_level_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'level'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_logfile_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile_new'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned long',
+ 'name' => 'modperl_debug_level',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_hash_tie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_hash_tied_object',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_sv_setref_uv',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'rv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'UV',
+ 'name' => 'uv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_uri_t *',
+ 'name' => 'modperl_uri_new',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_gensym',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'pack'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_error_strerror',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_croak',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_unselect',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'modperl_bucket_sv_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+];
+
+1;
diff --git a/2_0_13/xs/tables/current24/Apache2/ConstantsTable.pm b/2_0_13/xs/tables/current24/Apache2/ConstantsTable.pm
new file mode 100644
index 0000000..f54adfd
--- /dev/null
+++ b/2_0_13/xs/tables/current24/Apache2/ConstantsTable.pm
@@ -0,0 +1,545 @@
+package Apache2::ConstantsTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by Apache2::ParseSource/0.02
+# ! Mon Jul 1 12:38:09 2013
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$Apache2::ConstantsTable = {
+ 'ModPerl' => {
+ 'common' => [
+ 'MODPERL_RC_EXIT'
+ ]
+ },
+ 'Apache2::Const' => {
+ 'types' => [
+ 'DIR_MAGIC_TYPE'
+ ],
+ 'satisfy' => [
+ 'SATISFY_ALL',
+ 'SATISFY_ANY',
+ 'SATISFY_NOSPEC'
+ ],
+ 'remotehost' => [
+ 'REMOTE_HOST',
+ 'REMOTE_NAME',
+ 'REMOTE_NOLOOKUP',
+ 'REMOTE_DOUBLE_REV'
+ ],
+ 'proxy' => [
+ 'PROXYREQ_NONE',
+ 'PROXYREQ_PROXY',
+ 'PROXYREQ_REVERSE',
+ 'PROXYREQ_RESPONSE'
+ ],
+ 'platform' => [
+ 'LF',
+ 'CR',
+ 'CRLF',
+ 'CRLF_ASCII'
+ ],
+ 'override' => [
+ 'OR_NONE',
+ 'OR_LIMIT',
+ 'OR_OPTIONS',
+ 'OR_FILEINFO',
+ 'OR_AUTHCFG',
+ 'OR_INDEXES',
+ 'OR_UNSET',
+ 'ACCESS_CONF',
+ 'RSRC_CONF',
+ 'EXEC_ON_READ',
+ 'OR_ALL'
+ ],
+ 'options' => [
+ 'OPT_NONE',
+ 'OPT_INDEXES',
+ 'OPT_INCLUDES',
+ 'OPT_SYM_LINKS',
+ 'OPT_EXECCGI',
+ 'OPT_UNSET',
+ 'OPT_INC_WITH_EXEC',
+ 'OPT_SYM_OWNER',
+ 'OPT_MULTI',
+ 'OPT_ALL'
+ ],
+ 'mpmq' => [
+ 'AP_MPMQ_NOT_SUPPORTED',
+ 'AP_MPMQ_STATIC',
+ 'AP_MPMQ_DYNAMIC',
+ 'AP_MPMQ_STARTING',
+ 'AP_MPMQ_RUNNING',
+ 'AP_MPMQ_STOPPING',
+ 'AP_MPMQ_MAX_DAEMON_USED',
+ 'AP_MPMQ_IS_THREADED',
+ 'AP_MPMQ_IS_FORKED',
+ 'AP_MPMQ_HARD_LIMIT_DAEMONS',
+ 'AP_MPMQ_HARD_LIMIT_THREADS',
+ 'AP_MPMQ_MAX_THREADS',
+ 'AP_MPMQ_MIN_SPARE_DAEMONS',
+ 'AP_MPMQ_MIN_SPARE_THREADS',
+ 'AP_MPMQ_MAX_SPARE_DAEMONS',
+ 'AP_MPMQ_MAX_SPARE_THREADS',
+ 'AP_MPMQ_MAX_REQUESTS_DAEMON',
+ 'AP_MPMQ_MAX_DAEMONS',
+ 'AP_MPMQ_MPM_STATE',
+ 'AP_MPMQ_IS_ASYNC',
+ 'AP_MPMQ_GENERATION',
+ 'AP_MPMQ_HAS_SERF'
+ ],
+ 'methods' => [
+ 'M_GET',
+ 'M_PUT',
+ 'M_POST',
+ 'M_DELETE',
+ 'M_CONNECT',
+ 'M_OPTIONS',
+ 'M_TRACE',
+ 'M_PATCH',
+ 'M_PROPFIND',
+ 'M_PROPPATCH',
+ 'M_MKCOL',
+ 'M_COPY',
+ 'M_MOVE',
+ 'M_LOCK',
+ 'M_UNLOCK',
+ 'M_VERSION_CONTROL',
+ 'M_CHECKOUT',
+ 'M_UNCHECKOUT',
+ 'M_CHECKIN',
+ 'M_UPDATE',
+ 'M_LABEL',
+ 'M_REPORT',
+ 'M_MKWORKSPACE',
+ 'M_MKACTIVITY',
+ 'M_BASELINE_CONTROL',
+ 'M_MERGE',
+ 'M_INVALID',
+ 'METHODS'
+ ],
+ 'log' => [
+ 'APLOG_EMERG',
+ 'APLOG_ALERT',
+ 'APLOG_CRIT',
+ 'APLOG_ERR',
+ 'APLOG_WARNING',
+ 'APLOG_NOTICE',
+ 'APLOG_INFO',
+ 'APLOG_DEBUG',
+ 'APLOG_TRACE1',
+ 'APLOG_TRACE2',
+ 'APLOG_TRACE3',
+ 'APLOG_TRACE4',
+ 'APLOG_TRACE5',
+ 'APLOG_TRACE6',
+ 'APLOG_TRACE7',
+ 'APLOG_TRACE8',
+ 'APLOG_LEVELMASK',
+ 'APLOG_TOCLIENT',
+ 'APLOG_STARTUP',
+ 'APLOG_NO_MODULE',
+ 'APLOG_MODULE_INDEX'
+ ],
+ 'input_mode' => [
+ 'AP_MODE_READBYTES',
+ 'AP_MODE_GETLINE',
+ 'AP_MODE_EATCRLF',
+ 'AP_MODE_SPECULATIVE',
+ 'AP_MODE_EXHAUSTIVE',
+ 'AP_MODE_INIT'
+ ],
+ 'http' => [
+ 'HTTP_CONTINUE',
+ 'HTTP_SWITCHING_PROTOCOLS',
+ 'HTTP_PROCESSING',
+ 'HTTP_OK',
+ 'HTTP_CREATED',
+ 'HTTP_ACCEPTED',
+ 'HTTP_NON_AUTHORITATIVE',
+ 'HTTP_NO_CONTENT',
+ 'HTTP_RESET_CONTENT',
+ 'HTTP_PARTIAL_CONTENT',
+ 'HTTP_MULTI_STATUS',
+ 'HTTP_ALREADY_REPORTED',
+ 'HTTP_IM_USED',
+ 'HTTP_MULTIPLE_CHOICES',
+ 'HTTP_MOVED_PERMANENTLY',
+ 'HTTP_MOVED_TEMPORARILY',
+ 'HTTP_SEE_OTHER',
+ 'HTTP_NOT_MODIFIED',
+ 'HTTP_USE_PROXY',
+ 'HTTP_TEMPORARY_REDIRECT',
+ 'HTTP_PERMANENT_REDIRECT',
+ 'HTTP_BAD_REQUEST',
+ 'HTTP_UNAUTHORIZED',
+ 'HTTP_PAYMENT_REQUIRED',
+ 'HTTP_FORBIDDEN',
+ 'HTTP_NOT_FOUND',
+ 'HTTP_METHOD_NOT_ALLOWED',
+ 'HTTP_NOT_ACCEPTABLE',
+ 'HTTP_PROXY_AUTHENTICATION_REQUIRED',
+ 'HTTP_REQUEST_TIME_OUT',
+ 'HTTP_CONFLICT',
+ 'HTTP_GONE',
+ 'HTTP_LENGTH_REQUIRED',
+ 'HTTP_PRECONDITION_FAILED',
+ 'HTTP_REQUEST_ENTITY_TOO_LARGE',
+ 'HTTP_REQUEST_URI_TOO_LARGE',
+ 'HTTP_UNSUPPORTED_MEDIA_TYPE',
+ 'HTTP_RANGE_NOT_SATISFIABLE',
+ 'HTTP_EXPECTATION_FAILED',
+ 'HTTP_UNPROCESSABLE_ENTITY',
+ 'HTTP_LOCKED',
+ 'HTTP_FAILED_DEPENDENCY',
+ 'HTTP_UPGRADE_REQUIRED',
+ 'HTTP_PRECONDITION_REQUIRED',
+ 'HTTP_TOO_MANY_REQUESTS',
+ 'HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE',
+ 'HTTP_INTERNAL_SERVER_ERROR',
+ 'HTTP_NOT_IMPLEMENTED',
+ 'HTTP_BAD_GATEWAY',
+ 'HTTP_SERVICE_UNAVAILABLE',
+ 'HTTP_GATEWAY_TIME_OUT',
+ 'HTTP_VARIANT_ALSO_VARIES',
+ 'HTTP_INSUFFICIENT_STORAGE',
+ 'HTTP_LOOP_DETECTED',
+ 'HTTP_NOT_EXTENDED',
+ 'HTTP_NETWORK_AUTHENTICATION_REQUIRED'
+ ],
+ 'filter_type' => [
+ 'AP_FTYPE_RESOURCE',
+ 'AP_FTYPE_CONTENT_SET',
+ 'AP_FTYPE_PROTOCOL',
+ 'AP_FTYPE_TRANSCODE',
+ 'AP_FTYPE_CONNECTION',
+ 'AP_FTYPE_NETWORK'
+ ],
+ 'context' => [
+ 'NOT_IN_VIRTUALHOST',
+ 'NOT_IN_LIMIT',
+ 'NOT_IN_DIRECTORY',
+ 'NOT_IN_LOCATION',
+ 'NOT_IN_FILES',
+ 'NOT_IN_HTACCESS',
+ 'NOT_IN_DIR_LOC_FILE',
+ 'GLOBAL_ONLY'
+ ],
+ 'conn_keepalive' => [
+ 'AP_CONN_UNKNOWN',
+ 'AP_CONN_CLOSE',
+ 'AP_CONN_KEEPALIVE'
+ ],
+ 'config' => [
+ 'DECLINE_CMD'
+ ],
+ 'common' => [
+ 'OK',
+ 'DECLINED',
+ 'DONE',
+ 'NOT_FOUND',
+ 'FORBIDDEN',
+ 'AUTH_REQUIRED',
+ 'SERVER_ERROR',
+ 'REDIRECT'
+ ],
+ 'cmd_how' => [
+ 'RAW_ARGS',
+ 'TAKE1',
+ 'TAKE2',
+ 'ITERATE',
+ 'ITERATE2',
+ 'FLAG',
+ 'NO_ARGS',
+ 'TAKE12',
+ 'TAKE3',
+ 'TAKE23',
+ 'TAKE123',
+ 'TAKE13',
+ 'TAKE_ARGV'
+ ],
+ 'authz_status' => [
+ 'AUTHZ_DENIED',
+ 'AUTHZ_GRANTED',
+ 'AUTHZ_NEUTRAL',
+ 'AUTHZ_GENERAL_ERROR',
+ 'AUTHZ_DENIED_NO_USER'
+ ],
+ 'authn_status' => [
+ 'AUTH_DENIED',
+ 'AUTH_GRANTED',
+ 'AUTH_USER_FOUND',
+ 'AUTH_USER_NOT_FOUND',
+ 'AUTH_GENERAL_ERROR'
+ ],
+ 'auth' => [
+ 'AUTHN_PROVIDER_GROUP',
+ 'AUTHZ_PROVIDER_GROUP',
+ 'AUTHN_PROVIDER_VERSION',
+ 'AUTHZ_PROVIDER_VERSION',
+ 'AUTHN_DEFAULT_PROVIDER',
+ 'AUTHN_PROVIDER_NAME_NOTE',
+ 'AUTHZ_PROVIDER_NAME_NOTE',
+ 'AUTHN_PREFIX',
+ 'AUTHZ_PREFIX',
+ 'AP_AUTH_INTERNAL_PER_URI',
+ 'AP_AUTH_INTERNAL_PER_CONF',
+ 'AP_AUTH_INTERNAL_MASK'
+ ]
+ },
+ 'APR::Const' => {
+ 'uri' => [
+ 'APR_URI_FTP_DEFAULT_PORT',
+ 'APR_URI_SSH_DEFAULT_PORT',
+ 'APR_URI_TELNET_DEFAULT_PORT',
+ 'APR_URI_GOPHER_DEFAULT_PORT',
+ 'APR_URI_HTTP_DEFAULT_PORT',
+ 'APR_URI_POP_DEFAULT_PORT',
+ 'APR_URI_NNTP_DEFAULT_PORT',
+ 'APR_URI_IMAP_DEFAULT_PORT',
+ 'APR_URI_PROSPERO_DEFAULT_PORT',
+ 'APR_URI_WAIS_DEFAULT_PORT',
+ 'APR_URI_LDAP_DEFAULT_PORT',
+ 'APR_URI_HTTPS_DEFAULT_PORT',
+ 'APR_URI_RTSP_DEFAULT_PORT',
+ 'APR_URI_SNEWS_DEFAULT_PORT',
+ 'APR_URI_ACAP_DEFAULT_PORT',
+ 'APR_URI_NFS_DEFAULT_PORT',
+ 'APR_URI_TIP_DEFAULT_PORT',
+ 'APR_URI_SIP_DEFAULT_PORT',
+ 'APR_URI_UNP_OMITSITEPART',
+ 'APR_URI_UNP_OMITUSER',
+ 'APR_URI_UNP_OMITPASSWORD',
+ 'APR_URI_UNP_OMITUSERINFO',
+ 'APR_URI_UNP_REVEALPASSWORD',
+ 'APR_URI_UNP_OMITPATHINFO',
+ 'APR_URI_UNP_OMITQUERY'
+ ],
+ 'table' => [
+ 'APR_OVERLAP_TABLES_SET',
+ 'APR_OVERLAP_TABLES_MERGE'
+ ],
+ 'status' => [
+ 'APR_TIMEUP'
+ ],
+ 'socket' => [
+ 'APR_SO_LINGER',
+ 'APR_SO_KEEPALIVE',
+ 'APR_SO_DEBUG',
+ 'APR_SO_NONBLOCK',
+ 'APR_SO_REUSEADDR',
+ 'APR_SO_SNDBUF',
+ 'APR_SO_RCVBUF',
+ 'APR_SO_DISCONNECTED'
+ ],
+ 'shutdown_how' => [
+ 'APR_SHUTDOWN_READ',
+ 'APR_SHUTDOWN_WRITE',
+ 'APR_SHUTDOWN_READWRITE'
+ ],
+ 'read_type' => [
+ 'APR_BLOCK_READ',
+ 'APR_NONBLOCK_READ'
+ ],
+ 'poll' => [
+ 'APR_POLLIN',
+ 'APR_POLLPRI',
+ 'APR_POLLOUT',
+ 'APR_POLLERR',
+ 'APR_POLLHUP',
+ 'APR_POLLNVAL',
+ 'APR_POLLSET_THREADSAFE',
+ 'APR_POLLSET_NOCOPY',
+ 'APR_POLLSET_WAKEABLE',
+ 'APR_POLLSET_NODEFAULT'
+ ],
+ 'lockmech' => [
+ 'APR_LOCK_FCNTL',
+ 'APR_LOCK_FLOCK',
+ 'APR_LOCK_SYSVSEM',
+ 'APR_LOCK_PROC_PTHREAD',
+ 'APR_LOCK_POSIXSEM',
+ 'APR_LOCK_DEFAULT'
+ ],
+ 'limit' => [
+ 'APR_LIMIT_CPU',
+ 'APR_LIMIT_MEM',
+ 'APR_LIMIT_NPROC',
+ 'APR_LIMIT_NOFILE'
+ ],
+ 'hook' => [
+ 'APR_HOOK_REALLY_FIRST',
+ 'APR_HOOK_FIRST',
+ 'APR_HOOK_MIDDLE',
+ 'APR_HOOK_LAST',
+ 'APR_HOOK_REALLY_LAST'
+ ],
+ 'fprot' => [
+ 'APR_FPROT_USETID',
+ 'APR_FPROT_UREAD',
+ 'APR_FPROT_UWRITE',
+ 'APR_FPROT_UEXECUTE',
+ 'APR_FPROT_GSETID',
+ 'APR_FPROT_GREAD',
+ 'APR_FPROT_GWRITE',
+ 'APR_FPROT_GEXECUTE',
+ 'APR_FPROT_WSTICKY',
+ 'APR_FPROT_WREAD',
+ 'APR_FPROT_WWRITE',
+ 'APR_FPROT_WEXECUTE',
+ 'APR_FPROT_OS_DEFAULT',
+ 'APR_FPROT_FILE_SOURCE_PERMS'
+ ],
+ 'fopen' => [
+ 'APR_FOPEN_READ',
+ 'APR_FOPEN_WRITE',
+ 'APR_FOPEN_CREATE',
+ 'APR_FOPEN_APPEND',
+ 'APR_FOPEN_TRUNCATE',
+ 'APR_FOPEN_BINARY',
+ 'APR_FOPEN_EXCL',
+ 'APR_FOPEN_BUFFERED',
+ 'APR_FOPEN_DELONCLOSE',
+ 'APR_FOPEN_XTHREAD',
+ 'APR_FOPEN_SHARELOCK',
+ 'APR_FOPEN_NOCLEANUP',
+ 'APR_FOPEN_SENDFILE_ENABLED',
+ 'APR_FOPEN_LARGEFILE',
+ 'APR_FOPEN_SPARSE'
+ ],
+ 'flock' => [
+ 'APR_FLOCK_SHARED',
+ 'APR_FLOCK_EXCLUSIVE',
+ 'APR_FLOCK_TYPEMASK',
+ 'APR_FLOCK_NONBLOCK'
+ ],
+ 'finfo' => [
+ 'APR_FINFO_LINK',
+ 'APR_FINFO_MTIME',
+ 'APR_FINFO_CTIME',
+ 'APR_FINFO_ATIME',
+ 'APR_FINFO_SIZE',
+ 'APR_FINFO_CSIZE',
+ 'APR_FINFO_DEV',
+ 'APR_FINFO_INODE',
+ 'APR_FINFO_NLINK',
+ 'APR_FINFO_TYPE',
+ 'APR_FINFO_USER',
+ 'APR_FINFO_GROUP',
+ 'APR_FINFO_UPROT',
+ 'APR_FINFO_GPROT',
+ 'APR_FINFO_WPROT',
+ 'APR_FINFO_ICASE',
+ 'APR_FINFO_NAME',
+ 'APR_FINFO_MIN',
+ 'APR_FINFO_IDENT',
+ 'APR_FINFO_OWNER',
+ 'APR_FINFO_PROT',
+ 'APR_FINFO_NORM',
+ 'APR_FINFO_DIRENT'
+ ],
+ 'filetype' => [
+ 'APR_FILETYPE_NOFILE',
+ 'APR_FILETYPE_REG',
+ 'APR_FILETYPE_DIR',
+ 'APR_FILETYPE_CHR',
+ 'APR_FILETYPE_BLK',
+ 'APR_FILETYPE_PIPE',
+ 'APR_FILETYPE_LNK',
+ 'APR_FILETYPE_SOCK',
+ 'APR_FILETYPE_UNKFILE'
+ ],
+ 'filepath' => [
+ 'APR_FILEPATH_NOTABOVEROOT',
+ 'APR_FILEPATH_SECUREROOTTEST',
+ 'APR_FILEPATH_SECUREROOT',
+ 'APR_FILEPATH_NOTRELATIVE',
+ 'APR_FILEPATH_NOTABSOLUTE',
+ 'APR_FILEPATH_NATIVE',
+ 'APR_FILEPATH_TRUENAME',
+ 'APR_FILEPATH_ENCODING_UNKNOWN',
+ 'APR_FILEPATH_ENCODING_LOCALE',
+ 'APR_FILEPATH_ENCODING_UTF8'
+ ],
+ 'error' => [
+ 'APR_ENOSTAT',
+ 'APR_ENOPOOL',
+ 'APR_EBADDATE',
+ 'APR_EINVALSOCK',
+ 'APR_ENOPROC',
+ 'APR_ENOTIME',
+ 'APR_ENODIR',
+ 'APR_ENOLOCK',
+ 'APR_ENOPOLL',
+ 'APR_ENOSOCKET',
+ 'APR_ENOTHREAD',
+ 'APR_ENOTHDKEY',
+ 'APR_EGENERAL',
+ 'APR_ENOSHMAVAIL',
+ 'APR_EBADIP',
+ 'APR_EBADMASK',
+ 'APR_EDSOOPEN',
+ 'APR_EABSOLUTE',
+ 'APR_ERELATIVE',
+ 'APR_EINCOMPLETE',
+ 'APR_EABOVEROOT',
+ 'APR_EBADPATH',
+ 'APR_EPATHWILD',
+ 'APR_ESYMNOTFOUND',
+ 'APR_EPROC_UNKNOWN',
+ 'APR_ENOTENOUGHENTROPY',
+ 'APR_EOF',
+ 'APR_EINIT',
+ 'APR_ENOTIMPL',
+ 'APR_EMISMATCH',
+ 'APR_EBUSY',
+ 'APR_EACCES',
+ 'APR_EEXIST',
+ 'APR_ENAMETOOLONG',
+ 'APR_ENOENT',
+ 'APR_ENOTDIR',
+ 'APR_ENOSPC',
+ 'APR_ENOMEM',
+ 'APR_EMFILE',
+ 'APR_ENFILE',
+ 'APR_EBADF',
+ 'APR_EINVAL',
+ 'APR_ESPIPE',
+ 'APR_EAGAIN',
+ 'APR_EINTR',
+ 'APR_ENOTSOCK',
+ 'APR_ECONNREFUSED',
+ 'APR_EINPROGRESS',
+ 'APR_ECONNABORTED',
+ 'APR_ECONNRESET',
+ 'APR_ETIMEDOUT',
+ 'APR_EHOSTUNREACH',
+ 'APR_ENETUNREACH',
+ 'APR_EFTYPE',
+ 'APR_EPIPE',
+ 'APR_EXDEV',
+ 'APR_ENOTEMPTY',
+ 'APR_EAFNOSUPPORT',
+ 'APR_EXCL',
+ 'APR_END',
+ 'APR_ENOKEY',
+ 'APR_ENOIV',
+ 'APR_EKEYTYPE',
+ 'APR_ENOSPACE',
+ 'APR_ECRYPT',
+ 'APR_EPADDING',
+ 'APR_EKEYLENGTH',
+ 'APR_ENOCIPHER',
+ 'APR_ENODIGEST',
+ 'APR_ENOENGINE',
+ 'APR_EINITENGINE',
+ 'APR_EREINIT'
+ ],
+ 'common' => [
+ 'APR_SUCCESS'
+ ]
+ }
+};
+
+
+1;
diff --git a/2_0_13/xs/tables/current24/Apache2/FunctionTable.pm b/2_0_13/xs/tables/current24/Apache2/FunctionTable.pm
new file mode 100644
index 0000000..adaa249
--- /dev/null
+++ b/2_0_13/xs/tables/current24/Apache2/FunctionTable.pm
@@ -0,0 +1,21265 @@
+package Apache2::FunctionTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by Apache2::ParseSource/0.02
+# ! Mon Jul 1 12:38:14 2013
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$Apache2::FunctionTable = [
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_abort_on_oom',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_cgi_vars',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_common_vars',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_file_conf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'core_dir_config *',
+ 'name' => 'conf'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'url_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_add_if_conf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'core_dir_config *',
+ 'name' => 'conf'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'url_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_input_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_add_loaded_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_add_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_directive_t *',
+ 'name' => 'ap_add_node',
+ 'args' => [
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'current'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'toadd'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'child'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_t *',
+ 'name' => 'ap_add_output_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_output_filters_by_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_per_dir_conf',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dir_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_per_url_conf',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'url_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_add_version_component',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'component'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_allow_methods',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reset'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_allow_options',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_allow_overrides',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_allow_standard_methods',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reset'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_append_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'delim'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_args_to_table',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_table_t **',
+ 'name' => 'table'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_auth_name',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_auth_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_basic_http_header',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_bin2hex',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'src'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'srclen'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'dest'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_eoc_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_eoc_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_eor_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_eor_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_error_create',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'error'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'ap_bucket_error_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'error'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_build_config',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'conf_pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_build_cont_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'current'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'curr_parent'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'orig_directive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_byterange_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_calc_scoreboard_size',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_calloc',
+ 'args' => [
+ {
+ 'type' => 'size_t',
+ 'name' => 'nelem'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_cfg_closefile',
+ 'args' => [
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cfg_getc',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cfg_getline',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsize'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_check_cmd_context',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'forbidden'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_check_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cleanup_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_clear_auth_internal',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_clear_method_list',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_close_listeners',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_close_piped_log',
+ 'args' => [
+ {
+ 'type' => 'piped_log *',
+ 'name' => 'pl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_close_selected_listeners',
+ 'args' => [
+ {
+ 'type' => 'ap_slave_t *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_construct_server',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_construct_url',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_content_length_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_content_type_tolower',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_context_document_root',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_context_prefix',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cookie_check_string',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cookie_read',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'remove'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cookie_remove',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'attrs'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cookie_remove2',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name2'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'attrs2'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cookie_write',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'attrs'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'maxage'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_cookie_write2',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name2'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'attrs2'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'maxage'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_copy_method_list',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'dest'
+ },
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_core_child_status',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'ap_generation_t',
+ 'name' => 'gen'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'slot'
+ },
+ {
+ 'type' => 'mpm_child_status',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_core_input_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_core_output_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_core_reorder_directories',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_core_translate',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_count_dirs',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t*',
+ 'name' => 'ap_create_conn_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char **',
+ 'name' => 'ap_create_environment',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t *',
+ 'name' => 'ap_create_per_dir_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t*',
+ 'name' => 'ap_create_request_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_create_sb_handle',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t **',
+ 'name' => 'new_sbh'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'child_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'thread_num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_create_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_scoreboard_e',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_custom_response',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_dbd_t*',
+ 'name' => 'ap_dbd_acquire',
+ 'args' => [
+ {
+ 'type' => 'request_rec*',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_dbd_t*',
+ 'name' => 'ap_dbd_cacquire',
+ 'args' => [
+ {
+ 'type' => 'conn_rec*',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_dbd_close',
+ 'args' => [
+ {
+ 'type' => 'server_rec*',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'ap_dbd_t*',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_dbd_t*',
+ 'name' => 'ap_dbd_open',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t*',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'server_rec*',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_dbd_prepare',
+ 'args' => [
+ {
+ 'type' => 'server_rec*',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_destroy_sub_req',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_die',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_directory_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_discard_request_body',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_document_root',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_dump_mutexes',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'out'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_error_log2stderr',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_escape_errorlog_item',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dest'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'buflen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_html2',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'toasc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_logitem',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_path_segment',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_path_segment_buffer',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_quotes',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'instring'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_shell_cmd',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_urlencoded',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_escape_urlencoded_buffer',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_exists_config_define',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_exists_scoreboard_image',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_explode_recent_gmt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'tm'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_explode_recent_localtime',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'tm'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_expr_exec',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const ap_expr_info_t *',
+ 'name' => 'expr'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_expr_exec_ctx',
+ 'args' => [
+ {
+ 'type' => 'ap_expr_eval_ctx_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_expr_exec_re',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const ap_expr_info_t *',
+ 'name' => 'expr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t *',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_expr_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_expr_lookup_default',
+ 'args' => [
+ {
+ 'type' => 'ap_expr_lookup_parms *',
+ 'name' => 'parms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_expr_parse',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'ap_expr_info_t *',
+ 'name' => 'info'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'expr'
+ },
+ {
+ 'type' => 'ap_expr_lookup_fn_t *',
+ 'name' => 'lookup_fn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_expr_info_t *',
+ 'name' => 'ap_expr_parse_cmd_mi',
+ 'args' => [
+ {
+ 'type' => 'const cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'expr'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ },
+ {
+ 'type' => 'ap_expr_lookup_fn_t *',
+ 'name' => 'lookup_fn'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_expr_str_exec',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const ap_expr_info_t *',
+ 'name' => 'expr'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_expr_str_exec_re',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const ap_expr_info_t *',
+ 'name' => 'expr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t *',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fatal_signal_child_setup',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fatal_signal_setup',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'in_pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fflush',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_field_noparam',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'intype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_file_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_filter_flush',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_filter_protocol',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t*',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'proto_flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_finalize_request_protocol',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_finalize_sub_req_protocol',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'sub_r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_child_by_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'pid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const command_rec *',
+ 'name' => 'ap_find_command',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const command_rec *',
+ 'name' => 'cmds'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const command_rec *',
+ 'name' => 'ap_find_command_in_modules',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'cmd_name'
+ },
+ {
+ 'type' => 'module **',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_last_token',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tok'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'module *',
+ 'name' => 'ap_find_linked_module',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_list_item',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tok'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_find_module_name',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_find_module_short_name',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_path_info',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path_info'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_find_token',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tok'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_fini_vhost_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'main_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_fixup_virtual_hosts',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'main_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_flush_conn',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fprintf',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_fputstrs',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_get_basic_auth_pw',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'pw'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_get_brigade',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bucket'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'long',
+ 'name' => 'ap_get_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsiz'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_get_conn_module_loglevel',
+ 'args' => [
+ {
+ 'type' => 'const conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_get_conn_server_module_loglevel',
+ 'args' => [
+ {
+ 'type' => 'const conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_socket_t *',
+ 'name' => 'ap_get_conn_socket',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_get_core_module_config',
+ 'args' => [
+ {
+ 'type' => 'const ap_conf_vector_t *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_get_input_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_off_t',
+ 'name' => 'ap_get_limit_req_body',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_get_limit_xml_body',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_get_list_item',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'field'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_loadavg',
+ 'args' => [
+ {
+ 'type' => 'ap_loadavg_t *',
+ 'name' => 'ld'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_get_local_host',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_mime_headers',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_mime_headers_core',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_get_module_config',
+ 'args' => [
+ {
+ 'type' => 'const ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'const module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_get_output_filter_handle',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_remote_host',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'conn'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dir_config'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'str_is_ip'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_remote_logname',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_get_request_module_loglevel',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void **',
+ 'name' => 'ap_get_request_note',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'note_num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'global_score *',
+ 'name' => 'ap_get_scoreboard_global',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'process_score *',
+ 'name' => 'ap_get_scoreboard_process',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'x'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'worker_score *',
+ 'name' => 'ap_get_scoreboard_worker',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'worker_score *',
+ 'name' => 'ap_get_scoreboard_worker_from_indexes',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'child_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'thread_num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_banner',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_built',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_description',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_get_server_module_loglevel',
+ 'args' => [
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_name',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_name_for_url',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'ap_get_server_port',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'ap_get_server_protocol',
+ 'args' => [
+ {
+ 'type' => 'server_rec*',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_server_revision',
+ 'args' => [
+ {
+ 'type' => 'ap_version_t *',
+ 'name' => 'version'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_server_version',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_get_sload',
+ 'args' => [
+ {
+ 'type' => 'ap_sload_t *',
+ 'name' => 'ld'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_get_status_line',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_get_token',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'accept_line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'accept_white'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_getline',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'fold'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_getparents',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_conf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_conf_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_nulls',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_nulls_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'stop'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_white',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_getword_white_nc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_global_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'instance_id'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'gid_t',
+ 'name' => 'ap_gname2id',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_access_checker',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_access_checker_ex',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_ex_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_auth_checker',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_auth_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_access',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_access_ex',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_ex_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_authn',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_check_user_id_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_authz',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_auth_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_config',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_check_config_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_check_user_id',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_check_user_id_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_child_init',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_child_init_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_child_status',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_child_status_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_create_connection',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_create_connection_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_create_request',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_create_request_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_default_port',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_default_port_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_drop_privileges',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_drop_privileges_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_end_generation',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_end_generation_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_error_log',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_error_log_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_expr_lookup',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_expr_lookup_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_fixups',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_fixups_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_generate_log_id',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_generate_log_id_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_access_checker',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_access_checker_ex',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_auth_checker',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_check_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_check_user_id',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_child_init',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_child_status',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_create_connection',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_create_request',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_default_port',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_drop_privileges',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_end_generation',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_error_log',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_expr_lookup',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_fixups',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_generate_log_id',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_get_mgmt_items',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_get_suexec_identity',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_handler',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_header_parser',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_http_scheme',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_insert_error_filter',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_insert_filter',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_insert_network_bucket',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_log_transaction',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_map_to_storage',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_get_mgmt_items',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_get_mgmt_items_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_monitor',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_mpm_get_name',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_mpm_query',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_mpm_register_timed_callback',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_note_auth_failure',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_open_logs',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_optional_fn_retrieve',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_post_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_post_read_request',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_connection',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_pre_read_request',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_process_connection',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_quick_handler',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_session_decode',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_session_encode',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_session_load',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_session_save',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_status_hook',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_get_suexec_identity',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_get_suexec_identity_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_test_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_translate_name',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_type_checker',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_watchdog_exit',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_watchdog_init',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_watchdog_need',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_hook_get_watchdog_step',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_handler_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_header_parser',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_header_parser_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_http_scheme',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_http_scheme_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_insert_error_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_insert_error_filter_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_insert_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_insert_filter_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_insert_network_bucket',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_insert_network_bucket_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_log_transaction',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_log_transaction_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_map_to_storage',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_map_to_storage_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_monitor',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_monitor_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_mpm',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_mpm_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_mpm_get_name',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_mpm_get_name_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_mpm_query',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_mpm_query_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_mpm_register_timed_callback',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_mpm_register_timed_callback_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_note_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_note_auth_failure_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_open_logs',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_open_logs_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_optional_fn_retrieve',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_optional_fn_retrieve_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_post_config',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_post_config_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_post_read_request',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_post_read_request_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_config',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_config_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_connection_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_mpm',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_mpm_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_pre_read_request',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_pre_read_request_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_process_connection',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_process_connection_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_quick_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_quick_handler_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_session_decode',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_session_decode_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_session_encode',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_session_encode_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_session_load',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_session_load_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_session_save',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_session_save_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_status_hook',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_status_hook_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_test_config',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_test_config_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_translate_name',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_translate_name_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_type_checker',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_type_checker_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_watchdog_exit',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_exit_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_watchdog_init',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_init_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_watchdog_need',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_need_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_hook_watchdog_step',
+ 'args' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_step_t *',
+ 'name' => 'pf'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_ht_time',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'gmt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_http_chunk_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_http_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_http_header_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_http_outerror_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_if_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_increment_counts',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_ind',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_index_of_response',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_init_rng',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_init_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'shared_score'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_init_vhost_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_init_virtual_host',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'main_server'
+ },
+ {
+ 'type' => 'server_rec **',
+ 'name' => 'ps'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_internal_fast_redirect',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'sub_req'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_internal_redirect',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_internal_redirect_handler',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_invoke_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_directory',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_initial_req',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_matchexp',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_rdirectory',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_recursion_limit_exceeded',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_is_url',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'u'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_limit_section',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_lingering_close',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_list_provider_groups',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'ap_list_provider_names',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_listen_pre_config',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_location_walk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_assert',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szExp'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szFile'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nLine'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_cerror_',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg7'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_command_line',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_cserror_',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg8'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_error_',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg7'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_perror_',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg7'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_log_rerror_',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg7'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_logs_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_lookup_provider',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_make_content_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_dirstr_parent',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_dirstr_prefix',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_etag',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'force_weak'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_make_full_path',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_method_list_t *',
+ 'name' => 'ap_make_method_list',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_malloc',
+ 'args' => [
+ {
+ 'type' => 'size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_matches_request_vhost',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'host'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5_binary',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5contextTo64',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_md5digest',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'infile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_meets_conditions',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_merge_log_config',
+ 'args' => [
+ {
+ 'type' => 'const struct ap_logconf *',
+ 'name' => 'old_conf'
+ },
+ {
+ 'type' => 'struct ap_logconf *',
+ 'name' => 'new_conf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_conf_vector_t*',
+ 'name' => 'ap_merge_per_dir_configs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'new_conf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_in_list',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_is_limited',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_list_add',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_list_remove',
+ 'args' => [
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_method_name_of',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'methnum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_number_of',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_method_register',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'methname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_method_registry_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_mpm_dump_pidfile',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'out'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_end_gen_helper',
+ 'args' => [
+ {
+ 'type' => 'void *unused',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_check',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_close',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_mpm_pod_killpg',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_open',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_pod_t **',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_pod_signal',
+ 'args' => [
+ {
+ 'type' => 'ap_pod_t *',
+ 'name' => 'pod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_query',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'query_code'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'result'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_register_timed_callback',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'ap_mpm_callback_fn_t *',
+ 'name' => 'cbfn'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'baton'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_mpm_rewrite_args',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mpm_safe_kill',
+ 'args' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'sig'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_coredumpdir',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_graceful_shutdown',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_max_mem_free',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_max_requests',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_pidfile',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_mpm_set_thread_stacksize',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_mutex_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_mutex_register',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'default_dir'
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'name' => 'default_mech'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'struct ap_logconf *',
+ 'name' => 'ap_new_log_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const struct ap_logconf *',
+ 'name' => 'old'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_no2slash',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_note_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_note_basic_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_note_digest_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_old_write_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_open_logs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's_main'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'piped_log *',
+ 'name' => 'ap_open_piped_log',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'program'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'piped_log *',
+ 'name' => 'ap_open_piped_log_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'program'
+ },
+ {
+ 'type' => 'apr_cmdtype_e',
+ 'name' => 'cmdtype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_open_stderr_log',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_os_create_privileged_process',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'newproc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'progname'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'env'
+ },
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_os_escape_path',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'partial'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_os_is_path_absolute',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_parse_form_data',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'struct ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_array_header_t **',
+ 'name' => 'ptr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'num'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_parse_htaccess',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t **',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_opts'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'override_list'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'access_name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_parse_log_level',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_parse_mutex',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_lockmech_e *',
+ 'name' => 'mutexmech'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'mutexfile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_parse_uri',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_parse_vhost_addrs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pass_brigade',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pass_brigade_fchk',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bucket'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_pbase64decode',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'bufcoded'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_pbase64encode',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_configfile_t *',
+ 'name' => 'ap_pcfg_open_custom',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'descr'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'apr_status_t (*getc_func) (char *ch, void *param)',
+ 'name' => 'arg3'
+ },
+ {
+ 'type' => 'apr_status_t (*gets_func) (void *buf, apr_size_t bufsiz, void *param)',
+ 'name' => 'arg4'
+ },
+ {
+ 'type' => 'apr_status_t (*close_func) (void *param)',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pcfg_openfile',
+ 'args' => [
+ {
+ 'type' => 'ap_configfile_t **',
+ 'name' => 'ret_cfg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_pcfg_strerror',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'ap_pcw_srv_cb_t',
+ 'name' => 'srv_cb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_default_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_directory_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'core_server_config *',
+ 'name' => 'sconf'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_files_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'core_dir_config *',
+ 'name' => 'dconf'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_location_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'core_server_config *',
+ 'name' => 'sconf'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'name' => 'dir_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pcw_walk_server_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ },
+ {
+ 'type' => 'ap_pcw_srv_cb_t',
+ 'name' => 'srv_cb'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_file_t *',
+ 'name' => 'ap_piped_log_read_fd',
+ 'args' => [
+ {
+ 'type' => 'piped_log *',
+ 'name' => 'pl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_file_t *',
+ 'name' => 'ap_piped_log_write_fd',
+ 'args' => [
+ {
+ 'type' => 'piped_log *',
+ 'name' => 'pl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pool_cleanup_set_null',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_regex_t *',
+ 'name' => 'ap_pregcomp',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cflags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_pregfree',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_regex_t *',
+ 'name' => 'reg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_pregsub',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t',
+ 'name' => 'pmatch'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pregsub_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'maxlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_proc_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'instance_id'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_async_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_process_child_status',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'apr_exit_why_e',
+ 'name' => 'why'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_process_config_tree',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_process_fnmatch_configs',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'optional'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_process_request_after_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_process_request_internal',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_process_resource_config',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_psignature',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'prefix'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_pstr2_alnum',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'src'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'dest'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_random_insecure_bytes',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_random_parent_after_fork',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'ap_random_pick',
+ 'args' => [
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'min'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'max'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'ap_rationalize_mtime',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'server_rec *',
+ 'name' => 'ap_read_config',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'config_name'
+ },
+ {
+ 'type' => 'ap_directive_t **',
+ 'name' => 'conftree'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_read_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'pid_t *',
+ 'name' => 'mypid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_read_request',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_realloc',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'ptr'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_recent_ctime',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_recent_ctime_ex',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'option'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_recent_rfc822_date',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_reclaim_child_processes',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'terminate'
+ },
+ {
+ 'type' => 'ap_reclaim_callback_fn_t *',
+ 'name' => 'mpm_callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_regcomp',
+ 'args' => [
+ {
+ 'type' => 'ap_regex_t *',
+ 'name' => 'preg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'regex'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cflags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_regerror',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'errcode'
+ },
+ {
+ 'type' => 'const ap_regex_t *',
+ 'name' => 'preg'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'errbuf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'errbuf_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_regexec',
+ 'args' => [
+ {
+ 'type' => 'const ap_regex_t *',
+ 'name' => 'preg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t *',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'eflags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_regexec_len',
+ 'args' => [
+ {
+ 'type' => 'const ap_regex_t *',
+ 'name' => 'preg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buff'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t *',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'eflags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_regfree',
+ 'args' => [
+ {
+ 'type' => 'ap_regex_t *',
+ 'name' => 'preg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_register_auth_provider',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'provider'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_config_hooks',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_errorlog_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'tag'
+ },
+ {
+ 'type' => 'ap_errorlog_handler_fn_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_extra_mpm_process',
+ 'args' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'ap_generation_t',
+ 'name' => 'gen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_hooks',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_register_input_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_in_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_register_log_hooks',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_register_output_filter',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_out_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_filter_rec_t *',
+ 'name' => 'ap_register_output_filter_protocol',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_out_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'proto_flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_register_provider',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'provider'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_register_request_note',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_relieve_child_processes',
+ 'args' => [
+ {
+ 'type' => 'ap_reclaim_callback_fn_t *',
+ 'name' => 'mpm_callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_input_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_loaded_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_module',
+ 'args' => [
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_output_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_remove_pid',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_reopen_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'shm'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'detached'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_replace_stderr_log',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_request_has_body',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_reserve_module_slots',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'count'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_reserve_module_slots_directive',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'directive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_reset_module_loglevels',
+ 'args' => [
+ {
+ 'type' => 'struct ap_logconf *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_resolve_env',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'word'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_response_code_string',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'error_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_retained_data_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_retained_data_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rflush',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_rgetline_core',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'read'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'fold'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rind',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rprintf',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rputc',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rputs',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_access_checker',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_access_checker_ex',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_auth_checker',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_check_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_check_user_id',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pchild'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_child_status',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'ap_generation_t',
+ 'name' => 'gen'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'slot'
+ },
+ {
+ 'type' => 'mpm_child_status',
+ 'name' => 'state'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'conn_rec *',
+ 'name' => 'ap_run_create_connection',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'csd'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'conn_id'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'alloc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_create_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'ap_run_default_port',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_drop_privileges',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pchild'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_end_generation',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_generation_t',
+ 'name' => 'gen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_error_log',
+ 'args' => [
+ {
+ 'type' => 'const ap_errorlog_info *',
+ 'name' => 'info'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'errstr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_expr_lookup',
+ 'args' => [
+ {
+ 'type' => 'ap_expr_lookup_parms *',
+ 'name' => 'parms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_fixups',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_generate_log_id',
+ 'args' => [
+ {
+ 'type' => 'const conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'id'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_get_mgmt_items',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_unix_identity_t *',
+ 'name' => 'ap_run_get_suexec_identity',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_header_parser',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_run_http_scheme',
+ 'args' => [
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_insert_error_filter',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_insert_filter',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_run_insert_network_bucket',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_log_transaction',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_map_to_storage',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_monitor',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_mpm',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server_conf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_run_mpm_get_name',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_mpm_query',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'query_code'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_status_t *',
+ 'name' => 'rv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_run_mpm_register_timed_callback',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'ap_mpm_callback_fn_t *',
+ 'name' => 'cbfn'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'baton'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_note_auth_failure',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'auth_type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_open_logs',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_optional_fn_retrieve',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_post_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_post_read_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_pre_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_pre_mpm',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'ap_scoreboard_e',
+ 'name' => 'sb_type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_pre_read_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_process_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_quick_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'lookup_uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_rewrite_args',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_run_session_decode',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'session_rec *',
+ 'name' => 'z'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_run_session_encode',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'session_rec *',
+ 'name' => 'z'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_run_session_load',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'session_rec **',
+ 'name' => 'z'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_run_session_save',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'session_rec *',
+ 'name' => 'z'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_status_hook',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_sub_req',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_run_test_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_translate_name',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_type_checker',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_watchdog_exit',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_watchdog_init',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_watchdog_need',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'singleton'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_run_watchdog_step',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_runtime_dir_relative',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rvputs',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rwrite',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ap_rxplus_t*',
+ 'name' => 'ap_rxplus_compile',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_rxplus_exec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'ap_rxplus_t *',
+ 'name' => 'rx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'newpattern'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_rxplus_match',
+ 'args' => [
+ {
+ 'type' => 'ap_rxplus_t *',
+ 'name' => 'rx'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'match'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char*',
+ 'name' => 'ap_rxplus_pmatch',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'ap_rxplus_t *',
+ 'name' => 'rx'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_satisfies',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_save_brigade',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade **',
+ 'name' => 'save_to'
+ },
+ {
+ 'type' => 'apr_bucket_brigade **',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_brigade',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_brigade_ex',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_core',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int (*getsfunc) (char *, int, void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'getsfunc_data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_core_ex',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int (*getsfunc) (char *, int, void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'getsfunc_data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_ex',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_strs',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'termch'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'termarg'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg4'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_scan_script_header_err_strs_ex',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'termch'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'termarg'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_send_error_response',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'recursive_error'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_send_fd',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_send_http_options',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_send_http_trace',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_send_interim_response',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'send_headers'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'ap_send_mmap',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_server_root_relative',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_accept_ranges',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'ap_set_config_vectors',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'section_vector'
+ },
+ {
+ 'type' => 'const char *section',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_content_length',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_content_type',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ct'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_context_info',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'prefix'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'document_root'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_core_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_deprecated',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_document_root',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'document_root'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_etag',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_extended_status',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_file_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_flag_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_flag_slot_char',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_int_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_set_keepalive',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_last_modified',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_listenbacklog',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_listener',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'char *const',
+ 'name' => 'argv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'const module *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_module_loglevel',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'struct ap_logconf *',
+ 'name' => 'l'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_mutex',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_name_virtual_host',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_receive_buffer_size',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_reqtail',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_scoreboard',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_send_buffer_size',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_server_protocol',
+ 'args' => [
+ {
+ 'type' => 'server_rec*',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'proto'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_string_slot',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_set_string_slot_lower',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'struct_ptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_set_sub_req_protocol',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'rnew'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_setup_auth_internal',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_setup_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_policy'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_setup_listeners',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_setup_make_content_type',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_setup_prelinked_modules',
+ 'args' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_should_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_show_directives',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_show_modules',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_show_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_signal_server',
+ 'args' => [
+ {
+ 'type' => 'int *',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_single_module_configure',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_size_list_item',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'field'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_soak_end_container',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'directive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_some_auth_required',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_start_lingering_close',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_state_query',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'query_code'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_str2_alnum',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'src'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'dest'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_str_tolower',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_str_toupper',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_strcasecmp_match',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'expected'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strcasestr',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strchr',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_strchr_c',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_strcmp_match',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'expected'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_stripprefix',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'bigstring'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'prefix'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strrchr',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_strrchr_c',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_strstr',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_strstr_c',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_lookup_dirent',
+ 'args' => [
+ {
+ 'type' => 'const apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'subtype'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_lookup_file',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_lookup_uri',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'ap_sub_req_method_uri',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'new_uri'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next_filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_sub_req_output_filter',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_sys_privileges_handlers',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'inc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_time_process_request',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_timeout_parameter_parse',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'timeout_parameter'
+ },
+ {
+ 'type' => 'apr_interval_time_t *',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'default_time_unit'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'uid_t',
+ 'name' => 'ap_uname2id',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unescape_all',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unescape_url',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unescape_url_keep2f',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'url'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'decode_slashes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unescape_urlencoded',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'query'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_unixd_accept',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'accepted'
+ },
+ {
+ 'type' => 'ap_listen_rec *',
+ 'name' => 'lr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptrans'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_unixd_set_global_mutex_perms',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'gmutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_unixd_set_proc_mutex_perms',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'pmutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_unixd_set_rlimit',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'struct rlimit **',
+ 'name' => 'plimit'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unixd_setup_child',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_unregister_extra_mpm_process',
+ 'args' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'ap_generation_t *',
+ 'name' => 'old_gen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_update_child_status',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_update_child_status_from_conn',
+ 'args' => [
+ {
+ 'type' => 'ap_sb_handle_t *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_update_child_status_from_indexes',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'child_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'thread_num'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_update_mtime',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'dependency_mtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_update_vhost_from_headers',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_update_vhost_given_ip',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'conn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_varbuf_cfg_getline',
+ 'args' => [
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'cfp'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'max_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_varbuf_free',
+ 'args' => [
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_varbuf_grow',
+ 'args' => [
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'new_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_varbuf_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'init_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'ap_varbuf_pdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'prepend'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'prepend_len'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'append'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'append_len'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'new_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'ap_varbuf_regsub',
+ 'args' => [
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'source'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t',
+ 'name' => 'pmatch'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'maxlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_varbuf_strmemcat',
+ 'args' => [
+ {
+ 'type' => 'struct ap_varbuf *',
+ 'name' => 'vb'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_vhost_iterate_given_conn',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'conn'
+ },
+ {
+ 'type' => 'ap_vhost_iterate_conn_cb',
+ 'name' => 'func_cb'
+ },
+ {
+ 'type' => 'void*',
+ 'name' => 'baton'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_vrprintf',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'vlist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'ap_wait_or_timeout',
+ 'args' => [
+ {
+ 'type' => 'apr_exit_why_e *',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'exitcode'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'ret'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'ap_walk_config',
+ 'args' => [
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'conftree'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'section_vector'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'ap_xml_parse_input',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_xml_doc **',
+ 'name' => 'pdoc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_memnode_t *',
+ 'name' => 'apr_allocator_alloc',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_allocator_create',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t **',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_free',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_memnode_t *',
+ 'name' => 'memnode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_max_free_set',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_thread_mutex_t *',
+ 'name' => 'apr_allocator_mutex_get',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_mutex_set',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_allocator_owner_get',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_allocator_owner_set',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_app_initialize',
+ 'args' => [
+ {
+ 'type' => 'int *',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'char const * const * *',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'char const * const * *',
+ 'name' => 'env'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_append',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'first'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'second'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_array_cat',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'dst'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_array_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_copy_hdr',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_array_make',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'elt_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_array_pop',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_array_pstrcat',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'arr'
+ },
+ {
+ 'type' => 'const char',
+ 'name' => 'sep'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_array_push',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'arr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int64_t',
+ 'name' => 'apr_atoi64',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_atomic_add32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_atomic_cas32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'with'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'cmp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void*',
+ 'name' => 'apr_atomic_casptr',
+ 'args' => [
+ {
+ 'type' => 'volatile void **',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'with'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'cmp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_atomic_dec32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_atomic_inc32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_atomic_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_atomic_read32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_atomic_set32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_atomic_sub32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_atomic_xchg32',
+ 'args' => [
+ {
+ 'type' => 'volatile apr_uint32_t *',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void*',
+ 'name' => 'apr_atomic_xchgptr',
+ 'args' => [
+ {
+ 'type' => 'volatile void **',
+ 'name' => 'mem'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'with'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_decode',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'plain_dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'coded_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_decode_binary',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'plain_dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'coded_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_decode_len',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'coded_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_encode',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'coded_dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'plain_src'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len_plain_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_encode_binary',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'coded_dst'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'plain_src'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len_plain_src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_base64_encode_len',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_brigade *',
+ 'name' => 'apr_brigade_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_flatten',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_brigade_insert_file',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_length',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_all'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_partition',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'point'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'after_point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_pflatten',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_printf',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg4'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_putc',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_puts',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_putstrs',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_brigade *',
+ 'name' => 'apr_brigade_split',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'e'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_brigade *',
+ 'name' => 'apr_brigade_split_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'e'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_split_line',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bbOut'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bbIn'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'maxbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_to_iovec',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nvec'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_vprintf',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'va'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_vputstrs',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'va'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_write',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_brigade_writev',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'name' => 'flush'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_bucket_alloc',
+ 'args' => [
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_alloc_t *',
+ 'name' => 'apr_bucket_alloc_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket_alloc_t *',
+ 'name' => 'apr_bucket_alloc_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_bucket_alloc_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_copy_notimpl',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'e'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_bucket_destroy_noop',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_eos_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_eos_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_file_create',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_file_enable_mmap',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'enabled'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_file_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_flush_create',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_flush_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_bucket_free',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'block'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_heap_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'void (*free_func)(void *data)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_heap_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'void (*free_func)(void *data)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_immortal_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_immortal_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_mmap_create',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_mmap_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pipe_create',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thispipe'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pipe_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thispipe'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pool_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_pool_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_setaside_noop',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_setaside_notimpl',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_shared_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_bucket_shared_destroy',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_shared_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_shared_split',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_simple_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket **',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_simple_split',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_socket_create',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thissock'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_socket_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thissock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_bucket_split_notimpl',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'point'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_transient_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'apr_bucket_transient_make',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbyte'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_collapse_spaces',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dest'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_cpystrn',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dst'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'src'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'dst_size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_cleanup',
+ 'args' => [
+ {
+ 'type' => 'apr_crypto_block_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_decrypt',
+ 'args' => [
+ {
+ 'type' => 'unsigned char **',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'outlen'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inlen'
+ },
+ {
+ 'type' => 'apr_crypto_block_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_decrypt_finish',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'outlen'
+ },
+ {
+ 'type' => 'apr_crypto_block_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_decrypt_init',
+ 'args' => [
+ {
+ 'type' => 'apr_crypto_block_t **',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'blockSize'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'iv'
+ },
+ {
+ 'type' => 'const apr_crypto_key_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_encrypt',
+ 'args' => [
+ {
+ 'type' => 'unsigned char **',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'outlen'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inlen'
+ },
+ {
+ 'type' => 'apr_crypto_block_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_encrypt_finish',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'outlen'
+ },
+ {
+ 'type' => 'apr_crypto_block_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_block_encrypt_init',
+ 'args' => [
+ {
+ 'type' => 'apr_crypto_block_t **',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'const unsigned char **',
+ 'name' => 'iv'
+ },
+ {
+ 'type' => 'const apr_crypto_key_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'blockSize'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_cleanup',
+ 'args' => [
+ {
+ 'type' => 'apr_crypto_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_crypto_driver_name',
+ 'args' => [
+ {
+ 'type' => 'const apr_crypto_driver_t *',
+ 'name' => 'driver'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_error',
+ 'args' => [
+ {
+ 'type' => 'const apu_err_t **',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'const apr_crypto_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_get_block_key_modes',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t **',
+ 'name' => 'modes'
+ },
+ {
+ 'type' => 'const apr_crypto_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_get_block_key_types',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t **',
+ 'name' => 'types'
+ },
+ {
+ 'type' => 'const apr_crypto_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_get_driver',
+ 'args' => [
+ {
+ 'type' => 'const apr_crypto_driver_t **',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'params'
+ },
+ {
+ 'type' => 'const apu_err_t **',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_make',
+ 'args' => [
+ {
+ 'type' => 'apr_crypto_t **',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'const apr_crypto_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'params'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_passphrase',
+ 'args' => [
+ {
+ 'type' => 'apr_crypto_key_t **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'ivSize'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pass'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'passLen'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'salt'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'saltLen'
+ },
+ {
+ 'type' => 'const apr_crypto_block_key_type_e',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const apr_crypto_block_key_mode_e',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'const int',
+ 'name' => 'doPad'
+ },
+ {
+ 'type' => 'const int',
+ 'name' => 'iterations'
+ },
+ {
+ 'type' => 'const apr_crypto_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_crypto_hash_t *',
+ 'name' => 'apr_crypto_sha256_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_crypto_shutdown',
+ 'args' => [
+ {
+ 'type' => 'const apr_crypto_driver_t *',
+ 'name' => 'driver'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ctime',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_date_checkmask',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'mask'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'apr_date_parse_http',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'date'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'apr_date_parse_rfc',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'date'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_check_conn',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbd_close',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbd_datum_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_row_t *',
+ 'name' => 'row'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'col'
+ },
+ {
+ 'type' => 'apr_dbd_type_e',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_dbd_error',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'errnum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_dbd_escape',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'string'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbd_get_driver',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const apr_dbd_driver_t **',
+ 'name' => 'driver'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_dbd_get_entry',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_row_t *',
+ 'name' => 'row'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'col'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_dbd_get_name',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_results_t *',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'col'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_get_row',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_results_t *',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'apr_dbd_row_t **',
+ 'name' => 'row'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'rownum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbd_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_dbd_name',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void*',
+ 'name' => 'apr_dbd_native_handle',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_num_cols',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_results_t *',
+ 'name' => 'res'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_num_tuples',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_results_t *',
+ 'name' => 'res'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbd_open',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'params'
+ },
+ {
+ 'type' => 'apr_dbd_t **',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbd_open_ex',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'params'
+ },
+ {
+ 'type' => 'apr_dbd_t **',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'error'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pbquery',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nrows'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'const void **',
+ 'name' => 'args'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pbselect',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'apr_dbd_results_t **',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'random'
+ },
+ {
+ 'type' => 'const void **',
+ 'name' => 'args'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pquery',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nrows'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nargs'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'args'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_prepare',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'query'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'label'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t **',
+ 'name' => 'statement'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pselect',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'apr_dbd_results_t **',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'random'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nargs'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'args'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pvbquery',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nrows'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pvbselect',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'apr_dbd_results_t **',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'random'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg6'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pvquery',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nrows'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg5'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_pvselect',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'apr_dbd_results_t **',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'random'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg6'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_query',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'nrows'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'statement'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_select',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'apr_dbd_results_t **',
+ 'name' => 'res'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'statement'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'random'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_set_dbname',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_transaction_end',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_transaction_t *',
+ 'name' => 'trans'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_transaction_mode_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_transaction_t *',
+ 'name' => 'trans'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_transaction_mode_set',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_dbd_transaction_t *',
+ 'name' => 'trans'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbd_transaction_start',
+ 'args' => [
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'apr_dbd_transaction_t **',
+ 'name' => 'trans'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dbm_close',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_dbm_exists',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_fetch',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_datum_t *',
+ 'name' => 'pvalue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_firstkey',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t *',
+ 'name' => 'pkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dbm_freedatum',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dbm_get_usednames',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used1'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_get_usednames_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used1'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'used2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_dbm_geterror',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'errcode'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'errbuf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'errbufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_nextkey',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t *',
+ 'name' => 'pkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_open',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t **',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_open_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t **',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dbm_store',
+ 'args' => [
+ {
+ 'type' => 'apr_dbm_t *',
+ 'name' => 'dbm'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'name' => 'value'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_close',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'thedir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_make',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_make_recursive',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_open',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t **',
+ 'name' => 'new_dir'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dirname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_read',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'thedir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_remove',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dir_rewind',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'thedir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_dso_error',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'dso'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dso_load',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t **',
+ 'name' => 'res_handle'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ctx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dso_sym',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_sym_t *',
+ 'name' => 'ressym'
+ },
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'symname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_dso_unload',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_dynamic_fn_register',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'apr_opt_fn_t *',
+ 'name' => 'pfn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_opt_fn_t *',
+ 'name' => 'apr_dynamic_fn_retrieve',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_env_delete',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'envvar'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_env_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'envvar'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_env_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'envvar'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_append',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_attrs_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_fileattrs_t',
+ 'name' => 'attributes'
+ },
+ {
+ 'type' => 'apr_fileattrs_t',
+ 'name' => 'attr_mask'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_buffer_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_file_buffer_size_get',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_close',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_copy',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_data_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_datasync',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_dup',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'old_file'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_dup2',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'old_file'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_eof',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int32_t',
+ 'name' => 'apr_file_flags_get',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_flush',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_getc',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_gets',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_info_get',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_inherit_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_inherit_unset',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_link',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_mktemp',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'fp'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'templ'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_mtime_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_name_get',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'new_path'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_namedpipe_create',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'newf'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flag'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_flags_stderr',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_flags_stdin',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_flags_stdout',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_stderr',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_stdin',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_open_stdout',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_perms_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_create',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'blocking'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_timeout_get',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thepipe'
+ },
+ {
+ 'type' => 'apr_interval_time_t *',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_pipe_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thepipe'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_file_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_file_printf',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fptr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_putc',
+ 'args' => [
+ {
+ 'type' => 'char',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_puts',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_read',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_read_full',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbytes'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'bytes_read'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_remove',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_rename',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'from_path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'to_path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_seek',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_seek_where_t',
+ 'name' => 'where'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_setaside',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'new_file'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'old_file'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_sync',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_trunc',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fp'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_ungetc',
+ 'args' => [
+ {
+ 'type' => 'char',
+ 'name' => 'ch'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_write',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_write_full',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbytes'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'bytes_written'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_writev',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_file_writev_full',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_encoding',
+ 'args' => [
+ {
+ 'type' => 'int *',
+ 'name' => 'style'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_list_merge',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'liststr'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'pathelts'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_list_split',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t **',
+ 'name' => 'pathelts'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'liststr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_merge',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'newpath'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'rootpath'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'addpath'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_filepath_name_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pathname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_root',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'rootpath'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'filepath'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_filepath_set',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_fnmatch',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'strings'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_fnmatch_test',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_generate_random_bytes',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_gethostname',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getnameinfo',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getopt',
+ 'args' => [
+ {
+ 'type' => 'apr_getopt_t *',
+ 'name' => 'os'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'opts'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'option_ch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'option_arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getopt_init',
+ 'args' => [
+ {
+ 'type' => 'apr_getopt_t **',
+ 'name' => 'os'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'argv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getopt_long',
+ 'args' => [
+ {
+ 'type' => 'apr_getopt_t *',
+ 'name' => 'os'
+ },
+ {
+ 'type' => 'const apr_getopt_option_t *',
+ 'name' => 'opts'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'option_ch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'option_arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_getservbyname',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'servname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_gid_get',
+ 'args' => [
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_gid_name_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'groupname'
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'name' => 'mech'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_global_mutex_lockfile',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_global_mutex_name',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_global_mutex_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_global_mutex_t *',
+ 'name' => 'theglobal_mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_trylock',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_global_mutex_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hash_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'h'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned int',
+ 'name' => 'apr_hash_count',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_hash_do',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_do_callback_fn_t *comp',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_index_t *',
+ 'name' => 'apr_hash_first',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_hash_get',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t',
+ 'name' => 'klen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_make',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_make_custom',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_hashfunc_t',
+ 'name' => 'hash_func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'h1'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'h2'
+ },
+ {
+ 'type' => 'void * (*merger)(apr_pool_t *p, const void *key, apr_ssize_t klen, const void *h1_val, const void *h2_val, const void *data)',
+ 'name' => 'arg3'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_index_t *',
+ 'name' => 'apr_hash_next',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_index_t *',
+ 'name' => 'hi'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_hash_t *',
+ 'name' => 'apr_hash_overlay',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'overlay'
+ },
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_hash_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_hash_t *',
+ 'name' => 'thehash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hash_set',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'ht'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t',
+ 'name' => 'klen'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hash_this',
+ 'args' => [
+ {
+ 'type' => 'apr_hash_index_t *',
+ 'name' => 'hi'
+ },
+ {
+ 'type' => 'const void **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t *',
+ 'name' => 'klen'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned int',
+ 'name' => 'apr_hashfunc_default',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_ssize_t *',
+ 'name' => 'klen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_debug_show',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_deregister_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_sort_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_hook_sort_register',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szHookName'
+ },
+ {
+ 'type' => 'apr_array_header_t **',
+ 'name' => 'aHooks'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_initialize',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ipsubnet_create',
+ 'args' => [
+ {
+ 'type' => 'apr_ipsubnet_t **',
+ 'name' => 'ipsub'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ipstr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'mask_or_numbits'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ipsubnet_test',
+ 'args' => [
+ {
+ 'type' => 'apr_ipsubnet_t *',
+ 'name' => 'ipsub'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_is_empty_array',
+ 'args' => [
+ {
+ 'type' => 'const apr_array_header_t *',
+ 'name' => 'a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_is_empty_table',
+ 'args' => [
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_itoa',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_get_option',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'LDAP *',
+ 'name' => 'ldap'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'option'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'outvalue'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_info',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'LDAP **',
+ 'name' => 'ldap'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'portno'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'secure'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_is_ldap_url',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_is_ldapi_url',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_is_ldaps_url',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ldap_rebind_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'LDAP *',
+ 'name' => 'ld'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'bindDN'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'bindPW'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ldap_rebind_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_ldap_rebind_remove',
+ 'args' => [
+ {
+ 'type' => 'LDAP *',
+ 'name' => 'ld'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_set_option',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'LDAP *',
+ 'name' => 'ldap'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'option'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'invalue'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_ssl_deinit',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_ssl_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'cert_auth_file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cert_file_type'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_url_parse',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'url_in'
+ },
+ {
+ 'type' => 'apr_ldap_url_desc_t **',
+ 'name' => 'ludpp'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_ldap_url_parse_ext',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'url_in'
+ },
+ {
+ 'type' => 'apr_ldap_url_desc_t **',
+ 'name' => 'ludpp'
+ },
+ {
+ 'type' => 'apr_ldap_err_t **',
+ 'name' => 'result_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_ltoa',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_match_glob',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'apr_array_header_t **',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mcast_hops',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_byte_t',
+ 'name' => 'ttl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mcast_interface',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'iface'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mcast_join',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'join'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'iface'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'source'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mcast_leave',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'iface'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'source'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mcast_loopback',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_byte_t',
+ 'name' => 'opt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_final',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_init',
+ 'args' => [
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_set_xlate',
+ 'args' => [
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md4_update',
+ 'args' => [
+ {
+ 'type' => 'apr_md4_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_encode',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'password'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'salt'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_final',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_init',
+ 'args' => [
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_set_xlate',
+ 'args' => [
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_md5_update',
+ 'args' => [
+ {
+ 'type' => 'apr_md5_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_add',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'const apr_size_t',
+ 'name' => 'data_size'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_memcache_add_multget_key',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'data_pool'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_hash_t **',
+ 'name' => 'values'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_add_server',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'apr_memcache_server_t *',
+ 'name' => 'server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'max_servers'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_memcache_t **',
+ 'name' => 'mc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_decr',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'apr_uint32_t *',
+ 'name' => 'new_value'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_disable_server',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'apr_memcache_server_t *',
+ 'name' => 'ms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_enable_server',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'apr_memcache_server_t *',
+ 'name' => 'ms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_memcache_server_t *',
+ 'name' => 'apr_memcache_find_server',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'host'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_memcache_server_t *',
+ 'name' => 'apr_memcache_find_server_hash',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const apr_uint32_t',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_memcache_server_t *',
+ 'name' => 'apr_memcache_find_server_hash_default',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const apr_uint32_t',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_getp',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_uint16_t *',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_memcache_hash',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const apr_size_t',
+ 'name' => 'data_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_memcache_hash_crc32',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const apr_size_t',
+ 'name' => 'data_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_memcache_hash_default',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const apr_size_t',
+ 'name' => 'data_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_incr',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'n'
+ },
+ {
+ 'type' => 'apr_uint32_t *',
+ 'name' => 'nv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_multgetp',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'data_pool'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'values'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_replace',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'const apr_size_t',
+ 'name' => 'data_size'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_server_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'host'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'min'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'smax'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'max'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'ttl'
+ },
+ {
+ 'type' => 'apr_memcache_server_t **',
+ 'name' => 'ns'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_set',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_t *',
+ 'name' => 'mc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'baton'
+ },
+ {
+ 'type' => 'const apr_size_t',
+ 'name' => 'data_size'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_stats',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_server_t *',
+ 'name' => 'ms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_memcache_stats_t **',
+ 'name' => 'stats'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_memcache_version',
+ 'args' => [
+ {
+ 'type' => 'apr_memcache_server_t *',
+ 'name' => 'ms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'baton'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_create',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t **',
+ 'name' => 'newmmap'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flag'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_dup',
+ 'args' => [
+ {
+ 'type' => 'apr_mmap_t **',
+ 'name' => 'new_mmap'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'old_mmap'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_mmap_offset',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_off_t_toa',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_optional_hook_add',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'void (*pfn)(void)',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPre'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSucc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'apr_optional_hook_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_os_default_encoding',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dir_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_dir_t **',
+ 'name' => 'thedir'
+ },
+ {
+ 'type' => 'apr_dir_t *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dir_put',
+ 'args' => [
+ {
+ 'type' => 'apr_dir_t **',
+ 'name' => 'dir'
+ },
+ {
+ 'type' => 'apr_os_dir_t *',
+ 'name' => 'thedir'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dso_handle_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_dso_handle_t *',
+ 'name' => 'dso'
+ },
+ {
+ 'type' => 'apr_dso_handle_t *',
+ 'name' => 'aprdso'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_dso_handle_put',
+ 'args' => [
+ {
+ 'type' => 'apr_dso_handle_t **',
+ 'name' => 'dso'
+ },
+ {
+ 'type' => 'apr_os_dso_handle_t',
+ 'name' => 'thedso'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_exp_time_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_exp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'aprtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_exp_time_put',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'aprtime'
+ },
+ {
+ 'type' => 'apr_os_exp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_file_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_file_put',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_global_mutex_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_global_mutex_t *',
+ 'name' => 'ospmutex'
+ },
+ {
+ 'type' => 'apr_global_mutex_t *',
+ 'name' => 'pmutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_imp_time_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_imp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'aprtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_imp_time_put',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'aprtime'
+ },
+ {
+ 'type' => 'apr_os_imp_time_t **',
+ 'name' => 'ostime'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char*',
+ 'name' => 'apr_os_locale_encoding',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_pipe_put',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_pipe_put_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_os_file_t *',
+ 'name' => 'thefile'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'register_cleanup'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_proc_mutex_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_proc_mutex_t *',
+ 'name' => 'ospmutex'
+ },
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'pmutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_proc_mutex_put',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'pmutex'
+ },
+ {
+ 'type' => 'apr_os_proc_mutex_t *',
+ 'name' => 'ospmutex'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_shm_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_shm_t *',
+ 'name' => 'osshm'
+ },
+ {
+ 'type' => 'apr_shm_t *',
+ 'name' => 'shm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_shm_put',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'shm'
+ },
+ {
+ 'type' => 'apr_os_shm_t *',
+ 'name' => 'osshm'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_sock_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_sock_t *',
+ 'name' => 'thesock'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_sock_make',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'apr_sock'
+ },
+ {
+ 'type' => 'apr_os_sock_info_t *',
+ 'name' => 'os_sock_info'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_sock_put',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_os_sock_t *',
+ 'name' => 'thesock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_os_thread_t',
+ 'name' => 'apr_os_thread_current',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_os_thread_equal',
+ 'args' => [
+ {
+ 'type' => 'apr_os_thread_t',
+ 'name' => 'tid1'
+ },
+ {
+ 'type' => 'apr_os_thread_t',
+ 'name' => 'tid2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_thread_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_thread_t **',
+ 'name' => 'thethd'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_thread_put',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t **',
+ 'name' => 'thd'
+ },
+ {
+ 'type' => 'apr_os_thread_t *',
+ 'name' => 'thethd'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_threadkey_get',
+ 'args' => [
+ {
+ 'type' => 'apr_os_threadkey_t *',
+ 'name' => 'thekey'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_threadkey_put',
+ 'args' => [
+ {
+ 'type' => 'apr_threadkey_t **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_os_threadkey_t *',
+ 'name' => 'thekey'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_os_uuid_get',
+ 'args' => [
+ {
+ 'type' => 'unsigned char *',
+ 'name' => 'uuid_data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_palloc',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_palloc_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_parse_addr_port',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'scope_id'
+ },
+ {
+ 'type' => 'apr_port_t *',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_password_get',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'prompt'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'pwbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_password_validate',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'passwd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_pcalloc_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_pmemdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'aprset'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'numsock'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'nsds'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_poll_method_defname',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollcb_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pollcb_t *',
+ 'name' => 'pollcb'
+ },
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'descriptor'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollcb_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pollcb_t **',
+ 'name' => 'pollcb'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollcb_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pollcb_t **',
+ 'name' => 'pollcb'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pollset_method_e',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollcb_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_pollcb_t *',
+ 'name' => 'pollcb'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_pollcb_cb_t',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'baton'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollcb_remove',
+ 'args' => [
+ {
+ 'type' => 'apr_pollcb_t *',
+ 'name' => 'pollcb'
+ },
+ {
+ 'type' => 'apr_pollfd_t *',
+ 'name' => 'descriptor'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'const apr_pollfd_t *',
+ 'name' => 'descriptor'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t **',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t **',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pollset_method_e',
+ 'name' => 'method'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_pollset_method_name',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'num'
+ },
+ {
+ 'type' => 'const apr_pollfd_t **',
+ 'name' => 'descriptors'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_remove',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ },
+ {
+ 'type' => 'const apr_pollfd_t *',
+ 'name' => 'descriptor'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pollset_wakeup',
+ 'args' => [
+ {
+ 'type' => 'apr_pollset_t *',
+ 'name' => 'pollset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_abortfunc_t',
+ 'name' => 'apr_pool_abort_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_abort_set',
+ 'args' => [
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abortfunc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_allocator_t *',
+ 'name' => 'apr_pool_allocator_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_child_cleanup_set',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*plain_cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_status_t (*child_cleanup)(void *)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_cleanup_for_exec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_cleanup_kill',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_cleanup_null',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_cleanup_register',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*plain_cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_status_t (*child_cleanup)(void *)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_cleanup_run',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_clear_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_core_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_core_ex_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_ex_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_unmanaged_ex',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_create_unmanaged_ex_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t **',
+ 'name' => 'newpool'
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'name' => 'abort_fn'
+ },
+ {
+ 'type' => 'apr_allocator_t *',
+ 'name' => 'allocator'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_destroy_debug',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file_line'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_initialize',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_pool_is_ancestor',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_note_subprocess',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'apr_kill_conditions_e',
+ 'name' => 'how'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_pool_parent_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_pre_cleanup_register',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_status_t (*plain_cleanup)(void *)',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_tag',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tag'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_pool_terminate',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_userdata_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_userdata_set',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_pool_userdata_setn',
+ 'args' => [
+ {
+ 'type' => 'const void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_create',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'new_proc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'progname'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'env'
+ },
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_detach',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'daemonize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_fork',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_kill',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'sig'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_child_init',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'name' => 'mech'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_proc_mutex_defname',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_proc_mutex_lockfile',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_proc_mutex_name',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_proc_mutex_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_proc_mutex_t *',
+ 'name' => 'theproc_mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_trylock',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_mutex_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_other_child_alert',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reason'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_refresh',
+ 'args' => [
+ {
+ 'type' => 'apr_other_child_rec_t *',
+ 'name' => 'ocr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reason'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_refresh_all',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'reason'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_register',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'void (*maintenance) (int reason, void *, int status)',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'write_fd'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_proc_other_child_unregister',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_wait',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'exitcode'
+ },
+ {
+ 'type' => 'apr_exit_why_e *',
+ 'name' => 'exitwhy'
+ },
+ {
+ 'type' => 'apr_wait_how_e',
+ 'name' => 'waithow'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_proc_wait_all_procs',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'exitcode'
+ },
+ {
+ 'type' => 'apr_exit_why_e *',
+ 'name' => 'exitwhy'
+ },
+ {
+ 'type' => 'apr_wait_how_e',
+ 'name' => 'waithow'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_addrspace_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'addrspace'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_err_set',
+ 'args' => [
+ {
+ 'type' => 'struct apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'child_err'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'parent_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_errfn_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_child_errfn_t *',
+ 'name' => 'errfn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_in_set',
+ 'args' => [
+ {
+ 'type' => 'struct apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'child_in'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'parent_in'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_child_out_set',
+ 'args' => [
+ {
+ 'type' => 'struct apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'child_out'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'parent_out'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_cmdtype_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_cmdtype_e',
+ 'name' => 'cmd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_create',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t **',
+ 'name' => 'new_attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_detach_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'detach'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_dir_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_error_check_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'chk'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_group_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'groupname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_io_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_limit_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'what'
+ },
+ {
+ 'type' => 'struct rlimit *',
+ 'name' => 'limit'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_procattr_user_set',
+ 'args' => [
+ {
+ 'type' => 'apr_procattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'password'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_psprintf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrcat',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrcatv',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'nbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrmemdup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pstrndup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_pvsprintf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'ap'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_create',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t **',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'queue_capacity'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_interrupt_all',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_pop',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_push',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned int',
+ 'name' => 'apr_queue_size',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_term',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_trypop',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_queue_trypush',
+ 'args' => [
+ {
+ 'type' => 'apr_queue_t *',
+ 'name' => 'queue'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_random_add_entropy',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'g'
+ },
+ {
+ 'type' => 'const void *',
+ 'name' => 'entropy_'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_random_after_fork',
+ 'args' => [
+ {
+ 'type' => 'apr_proc_t *',
+ 'name' => 'proc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_random_barrier',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'g'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_random_init',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'g'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_crypto_hash_t *',
+ 'name' => 'pool_hash'
+ },
+ {
+ 'type' => 'apr_crypto_hash_t *',
+ 'name' => 'key_hash'
+ },
+ {
+ 'type' => 'apr_crypto_hash_t *',
+ 'name' => 'prng_hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_random_insecure_bytes',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'g'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'random'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_random_insecure_ready',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_random_secure_bytes',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'g'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'random'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_random_secure_ready',
+ 'args' => [
+ {
+ 'type' => 'apr_random_t *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_random_t *',
+ 'name' => 'apr_random_standard_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_acquire',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'resource'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uint32_t',
+ 'name' => 'apr_reslist_acquired_count',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_reslist_cleanup_order_set',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_create',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t **',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'min'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'smax'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'hmax'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'ttl'
+ },
+ {
+ 'type' => 'apr_reslist_constructor',
+ 'name' => 'con'
+ },
+ {
+ 'type' => 'apr_reslist_destructor',
+ 'name' => 'de'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'params'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_invalidate',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'resource'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_maintain',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_reslist_release',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'resource'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_reslist_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'reslist'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rfc822_date',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'date_str'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_rmm_addr_get',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'apr_rmm_off_t',
+ 'name' => 'entity'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rmm_attach',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t **',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'apr_anylock_t *',
+ 'name' => 'lock'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'membuf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_rmm_off_t',
+ 'name' => 'apr_rmm_calloc',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'reqsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rmm_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rmm_detach',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rmm_free',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'apr_rmm_off_t',
+ 'name' => 'entity'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_rmm_init',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t **',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'apr_anylock_t *',
+ 'name' => 'lock'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'membuf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'memsize'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_rmm_off_t',
+ 'name' => 'apr_rmm_malloc',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'reqsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_rmm_off_t',
+ 'name' => 'apr_rmm_offset_get',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'entity'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_rmm_overhead_get',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'n'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_rmm_off_t',
+ 'name' => 'apr_rmm_realloc',
+ 'args' => [
+ {
+ 'type' => 'apr_rmm_t *',
+ 'name' => 'rmm'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'entity'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'reqsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_close',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'const apr_sdbm_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_fetch',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t *',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_firstkey',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_nextkey',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_open',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t **',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'perms'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_sdbm_rdonly',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_store',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'opt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sdbm_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_sdbm_t *',
+ 'name' => 'db'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_setup_signal_thread',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_base64',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'clear'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'out'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_final',
+ 'args' => [
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_init',
+ 'args' => [
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_update',
+ 'args' => [
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sha1_update_binary',
+ 'args' => [
+ {
+ 'type' => 'apr_sha1_ctx_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const unsigned char *',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'inputLen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_attach',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'apr_shm_baseaddr_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_create',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t **',
+ 'name' => 'm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'reqsize'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_detach',
+ 'args' => [
+ {
+ 'type' => 'apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_shm_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_shm_t *',
+ 'name' => 'theshm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_shm_remove',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_shm_size_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_shm_t *',
+ 'name' => 'm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_sigfunc_t *',
+ 'name' => 'apr_signal',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signo'
+ },
+ {
+ 'type' => 'apr_sigfunc_t *',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_signal_block',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_signal_description_get',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_signal_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pglobal'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_signal_thread',
+ 'args' => [
+ {
+ 'type' => 'int(*signal_handler)(int signum)',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_signal_unblock',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'signum'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_sleep',
+ 'args' => [
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_snprintf',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_sockaddr_equal',
+ 'args' => [
+ {
+ 'type' => 'const apr_sockaddr_t *',
+ 'name' => 'addr1'
+ },
+ {
+ 'type' => 'const apr_sockaddr_t *',
+ 'name' => 'addr2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_info_get',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t **',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_ip_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'addr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_sockaddr_ip_getbuf',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'buflen'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_accept',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'new_sock'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'connection_pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_addr_get',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t **',
+ 'name' => 'sa'
+ },
+ {
+ 'type' => 'apr_interface_e',
+ 'name' => 'which'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_atmark',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'atmark'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_atreadeof',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'atreadeof'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_bind',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_close',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_connect',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_create',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t **',
+ 'name' => 'new_sock'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'protocol'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_data_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup)(void*)',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_inherit_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_inherit_unset',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_listen',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'backlog'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_opt_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t *',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_opt_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_socket_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_socket_t *',
+ 'name' => 'thesocket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_protocol_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'protocol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_recv',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_recvfrom',
+ 'args' => [
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'from'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_send',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_sendfile',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'apr_hdtr_t *',
+ 'name' => 'hdtr'
+ },
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_sendto',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'where'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_sendv',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'const struct iovec *',
+ 'name' => 'vec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'nvec'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_shutdown',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'thesocket'
+ },
+ {
+ 'type' => 'apr_shutdown_how_e',
+ 'name' => 'how'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_timeout_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_interval_time_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_socket_type_get',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sock'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_stat',
+ 'args' => [
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_strerror',
+ 'args' => [
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'statcode'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'bufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_strfsize',
+ 'args' => [
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_strftime',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'retsize'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'max'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'tm'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const apr_strmatch_pattern *',
+ 'name' => 'apr_strmatch_precompile',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'case_sensitive'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_strnatcasecmp',
+ 'args' => [
+ {
+ 'type' => 'char const *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'char const *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_strnatcmp',
+ 'args' => [
+ {
+ 'type' => 'char const *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'char const *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_strtoff',
+ 'args' => [
+ {
+ 'type' => 'apr_off_t *',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'end'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int64_t',
+ 'name' => 'apr_strtoi64',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'end'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_strtok',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'str'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'sep'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'last'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_add',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_addn',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_clear',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_clone',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_compress',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_copy',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_table_do',
+ 'args' => [
+ {
+ 'type' => 'void *comp',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg3'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const apr_array_header_t *',
+ 'name' => 'apr_table_elts',
+ 'args' => [
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_table_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_make',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_mergen',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_overlap',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_table_t *',
+ 'name' => 'apr_table_overlay',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 'overlay'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 'base'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_set',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_setn',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_table_unset',
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_table_vdo',
+ 'args' => [
+ {
+ 'type' => 'void *comp',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'rec'
+ },
+ {
+ 'type' => 'const apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'vp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_temp_dir_get',
+ 'args' => [
+ {
+ 'type' => 'const char **',
+ 'name' => 'temp_dir'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_terminate',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_terminate2',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_text_append',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_text_header *',
+ 'name' => 'hdr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'text'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_broadcast',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t **',
+ 'name' => 'cond'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_cond_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_cond_t *',
+ 'name' => 'thethread_cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_signal',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_timedwait',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_cond_wait',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_cond_t *',
+ 'name' => 'cond'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t **',
+ 'name' => 'new_thread'
+ },
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_thread_start_t',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thread'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_data_set',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup) (void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thread'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_detach',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_exit',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'retval'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_join',
+ 'args' => [
+ {
+ 'type' => 'apr_status_t *',
+ 'name' => 'retval'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t **',
+ 'name' => 'mutex'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_lock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_mutex_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_mutex_t *',
+ 'name' => 'thethread_mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_trylock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_mutex_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'mutex'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_once',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_once_t *',
+ 'name' => 'control'
+ },
+ {
+ 'type' => 'void (*func)(void)',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_once_init',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_once_t **',
+ 'name' => 'control'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_busy_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t **',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'init_threads'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'max_threads'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_t *',
+ 'name' => 'thethread'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_idle_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_idle_max_get',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_idle_max_set',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'cnt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_interval_time_t',
+ 'name' => 'apr_thread_pool_idle_wait_get',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_interval_time_t',
+ 'name' => 'apr_thread_pool_idle_wait_set',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_push',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_thread_start_t',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'apr_byte_t',
+ 'name' => 'priority'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'owner'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_schedule',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_thread_start_t',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'time'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'owner'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_scheduled_tasks_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_task_owner_get',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'thd'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'owner'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_tasks_cancel',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'owner'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_tasks_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_tasks_high_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_tasks_run_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_thread_max_get',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_thread_max_set',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'cnt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_threads_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_threads_high_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_threads_idle_timeout_count',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_threshold_get',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'apr_thread_pool_threshold_set',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_pool_top',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_pool_t *',
+ 'name' => 'me'
+ },
+ {
+ 'type' => 'apr_thread_start_t',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'apr_byte_t',
+ 'name' => 'priority'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'owner'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_create',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t **',
+ 'name' => 'rwlock'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_destroy',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'apr_thread_rwlock_pool_get',
+ 'args' => [
+ {
+ 'type' => 'const apr_thread_rwlock_t *',
+ 'name' => 'thethread_rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_rdlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_tryrdlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_trywrlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_unlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_thread_rwlock_wrlock',
+ 'args' => [
+ {
+ 'type' => 'apr_thread_rwlock_t *',
+ 'name' => 'rwlock'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_thread_yield',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_create',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t **',
+ 'name' => 'new_attr'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_detach_get',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_detach_set',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'on'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_guardsize_set',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'guardsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadattr_stacksize_set',
+ 'args' => [
+ {
+ 'type' => 'apr_threadattr_t *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'stacksize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_data_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'threadkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_data_set',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_status_t (*cleanup) (void *)',
+ 'name' => 'arg2'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'threadkey'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_create',
+ 'args' => [
+ {
+ 'type' => 'apr_threadkey_t **',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void (*dest)(void *)',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_delete',
+ 'args' => [
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_get',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'new_mem'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_threadkey_private_set',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'priv'
+ },
+ {
+ 'type' => 'apr_threadkey_t *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_ansi_put',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_time_clock_hires',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_get',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_gmt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_gmt_get',
+ 'args' => [
+ {
+ 'type' => 'apr_time_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_lt',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_time_exp_tz',
+ 'args' => [
+ {
+ 'type' => 'apr_time_exp_t *',
+ 'name' => 'result'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'input'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'offs'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_time_t',
+ 'name' => 'apr_time_now',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_tokenize_to_argv',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg_str'
+ },
+ {
+ 'type' => 'char ***',
+ 'name' => 'argv_out'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'token_context'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_current',
+ 'args' => [
+ {
+ 'type' => 'apr_uid_t *',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_get',
+ 'args' => [
+ {
+ 'type' => 'apr_uid_t *',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_gid_t *',
+ 'name' => 'groupid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_homepath_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'dirname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uid_name_get',
+ 'args' => [
+ {
+ 'type' => 'char **',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'name' => 'userid'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uri_parse',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uri_parse_hostinfo',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostinfo'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_port_t',
+ 'name' => 'apr_uri_port_of_scheme',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'scheme_str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_uri_unparse',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_uri_t *',
+ 'name' => 'uptr'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_uuid_format',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'const apr_uuid_t *',
+ 'name' => 'uuid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_uuid_get',
+ 'args' => [
+ {
+ 'type' => 'apr_uuid_t *',
+ 'name' => 'uuid'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_uuid_parse',
+ 'args' => [
+ {
+ 'type' => 'apr_uuid_t *',
+ 'name' => 'uuid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uuid_str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_version',
+ 'args' => [
+ {
+ 'type' => 'apr_version_t *',
+ 'name' => 'pvsn'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_version_string',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_vformatter',
+ 'args' => [
+ {
+ 'type' => 'int (*flush_func)(apr_vformatter_buff_t *b)',
+ 'name' => 'arg0'
+ },
+ {
+ 'type' => 'apr_vformatter_buff_t *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'ap'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_vsnprintf',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ },
+ {
+ 'type' => 'va_list',
+ 'name' => 'ap'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_wait_for_io_or_timeout',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'for_read'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_close',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_conv_buffer',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'inbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'inbytes_left'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'outbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'outbytes_left'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int32_t',
+ 'name' => 'apr_xlate_conv_byte',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'unsigned char',
+ 'name' => 'inchar'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_open',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t **',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'topage'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'frompage'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xlate_sb_get',
+ 'args' => [
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'convset'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'onoff'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_xml_empty_elem',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_xml_elem *',
+ 'name' => 'elem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'apr_xml_insert_uri',
+ 'args' => [
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'uri_array'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xml_parse_file',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_xml_parser **',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'apr_xml_doc **',
+ 'name' => 'ppdoc'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'xmlfd'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'buffer_length'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_xml_parser *',
+ 'name' => 'apr_xml_parser_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xml_parser_done',
+ 'args' => [
+ {
+ 'type' => 'apr_xml_parser *',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'apr_xml_doc **',
+ 'name' => 'pdoc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'apr_xml_parser_feed',
+ 'args' => [
+ {
+ 'type' => 'apr_xml_parser *',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'apr_xml_parser_geterror',
+ 'args' => [
+ {
+ 'type' => 'apr_xml_parser *',
+ 'name' => 'parser'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'errbuf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'errbufsize'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_xml_quote_elem',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'elem'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'apr_xml_quote_string',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'quotes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'apr_xml_to_text',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const apr_xml_elem *',
+ 'name' => 'elem'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'style'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'namespaces'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'ns_map'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'pbuf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'psize'
+ }
+ ]
+ }
+];
+
+
+1;
diff --git a/2_0_13/xs/tables/current24/Apache2/StructureTable.pm b/2_0_13/xs/tables/current24/Apache2/StructureTable.pm
new file mode 100644
index 0000000..0bf8530
--- /dev/null
+++ b/2_0_13/xs/tables/current24/Apache2/StructureTable.pm
@@ -0,0 +1,5468 @@
+package Apache2::StructureTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by Apache2::ParseSource/0.02
+# ! Mon Jul 1 12:38:15 2013
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$Apache2::StructureTable = [
+ {
+ 'type' => 'ap_HOOK_access_checker_ex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_access_checker_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_auth_checker_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_check_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_check_user_id_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_child_init_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_child_status_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_create_connection_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_create_request_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_default_port_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_drop_privileges_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_end_generation_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_error_log_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_expr_lookup_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_fixups_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_generate_log_id_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_get_mgmt_items_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_get_suexec_identity_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_handler_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_header_parser_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_http_scheme_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_insert_error_filter_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_insert_filter_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_insert_network_bucket_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_log_transaction_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_map_to_storage_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_monitor_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_mpm_get_name_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_mpm_query_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_mpm_register_timed_callback_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_mpm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_note_auth_failure_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_open_logs_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_optional_fn_retrieve_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_post_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_post_read_request_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_connection_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_mpm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_pre_read_request_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_process_connection_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_quick_handler_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_session_decode_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_session_encode_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_session_load_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_session_save_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_status_hook_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_test_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_translate_name_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_type_checker_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_watchdog_exit_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_watchdog_init_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_watchdog_need_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_HOOK_watchdog_step_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_LINK_access_checker_ex_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_ex_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_access_checker_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_access_checker_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_auth_checker_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_auth_checker_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_check_config_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_check_config_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_check_user_id_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_check_user_id_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_child_init_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_child_init_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_child_status_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_child_status_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_create_connection_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_create_connection_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_create_request_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_create_request_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_default_port_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_default_port_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_drop_privileges_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_drop_privileges_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_end_generation_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_end_generation_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_error_log_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_error_log_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_expr_lookup_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_expr_lookup_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_fixups_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_fixups_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_generate_log_id_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_generate_log_id_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_get_mgmt_items_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_get_mgmt_items_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_get_suexec_identity_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_get_suexec_identity_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_handler_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_handler_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_header_parser_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_header_parser_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_http_scheme_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_http_scheme_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_insert_error_filter_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_insert_error_filter_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_insert_filter_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_insert_filter_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_insert_network_bucket_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_insert_network_bucket_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_log_transaction_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_log_transaction_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_map_to_storage_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_map_to_storage_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_monitor_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_monitor_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_mpm_get_name_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_mpm_get_name_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_mpm_query_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_mpm_query_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_mpm_register_timed_callback_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_mpm_register_timed_callback_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_mpm_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_mpm_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_note_auth_failure_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_note_auth_failure_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_open_logs_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_open_logs_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_optional_fn_retrieve_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_optional_fn_retrieve_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_post_config_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_post_config_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_post_read_request_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_post_read_request_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_config_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_config_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_connection_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_connection_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_mpm_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_mpm_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_pre_read_request_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_pre_read_request_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_process_connection_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_process_connection_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_quick_handler_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_quick_handler_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_session_decode_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_session_decode_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_session_encode_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_session_encode_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_session_load_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_session_load_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_session_save_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_session_save_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_status_hook_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_status_hook_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_test_config_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_test_config_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_translate_name_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_translate_name_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_type_checker_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_type_checker_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_watchdog_exit_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_exit_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_watchdog_init_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_init_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_watchdog_need_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_need_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_LINK_watchdog_step_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_HOOK_watchdog_step_t *',
+ 'name' => 'pFunc'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'szName'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszPredecessors'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'aszSuccessors'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nOrder'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_bucket_error',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_conf_vector_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_configfile_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_status_t(*) (char *ch, void *param)',
+ 'name' => 'getch'
+ },
+ {
+ 'type' => 'apr_status_t(*) (void *buf, apr_size_t bufsiz, void *param)',
+ 'name' => 'getstr'
+ },
+ {
+ 'type' => 'apr_status_t(*) (void *param)',
+ 'name' => 'close'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'param'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'line_number'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_conn_keepalive_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_cookie_do',
+ 'elts' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'encoded'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'new_cookies'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'duplicated'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_dbd_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_dbd_t *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'const apr_dbd_driver_t *',
+ 'name' => 'driver'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'prepared'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_directive_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'directive'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'first_child'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line_num'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'last'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_errorlog_format_item',
+ 'elts' => [
+ {
+ 'type' => 'ap_errorlog_handler_fn_t *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'min_loglevel'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_errorlog_handler',
+ 'elts' => [
+ {
+ 'type' => 'ap_errorlog_handler_fn_t *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_errorlog_handler_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_errorlog_info',
+ 'elts' => [
+ {
+ 'type' => 'const server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const request_rec *',
+ 'name' => 'rmain'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'using_syslog'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'startup'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'format'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_expr_eval_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ },
+ {
+ 'type' => 'const ap_expr_info_t *',
+ 'name' => 'info'
+ },
+ {
+ 'type' => 'ap_regmatch_t *',
+ 'name' => 're_pmatch'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 're_nmatch'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 're_source'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'vary_this'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'result_string'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reclvl'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_expr_info_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_expr_t *',
+ 'name' => 'root_node'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'line_number'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_expr_list_func_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_expr_lookup_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_expr_lookup_parms',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'const void **',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'const void **',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'err'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_expr_op_binary_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_expr_op_unary_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_expr_string_func_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_expr_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_expr_var_func_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_filter_func',
+ 'elts' => [
+ {
+ 'type' => 'ap_out_filter_func',
+ 'name' => 'out_func'
+ },
+ {
+ 'type' => 'ap_in_filter_func',
+ 'name' => 'in_func'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_provider_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_filter_rec_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_filter_func',
+ 'name' => 'filter_func'
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'name' => 'filter_init_func'
+ },
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'ap_filter_provider_t *',
+ 'name' => 'providers'
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'name' => 'ftype'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'debug'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'proto_flags'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_filter_rec_t *',
+ 'name' => 'frec'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ctx'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_filter_type',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_form_pair_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'value'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_generation_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_in_filter_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_init_filter_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_list_provider_groups_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_list_provider_names_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_listen_rec',
+ 'elts' => [
+ {
+ 'type' => 'ap_listen_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'sd'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'bind_addr'
+ },
+ {
+ 'type' => 'accept_function',
+ 'name' => 'accept_func'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'active'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'protocol'
+ },
+ {
+ 'type' => 'ap_slave_t *',
+ 'name' => 'slave'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_loadavg_t',
+ 'elts' => [
+ {
+ 'type' => 'float',
+ 'name' => 'loadavg'
+ },
+ {
+ 'type' => 'float',
+ 'name' => 'loadavg5'
+ },
+ {
+ 'type' => 'float',
+ 'name' => 'loadavg15'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_method_list_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_int64_t',
+ 'name' => 'method_mask'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'method_list'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_mgmt_item_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'description'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'ap_mgmt_type_e',
+ 'name' => 'vtype'
+ },
+ {
+ 'type' => 'ap_mgmt_value',
+ 'name' => 'v'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_mgmt_type_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_mgmt_value',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 's_value'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'i_value'
+ },
+ {
+ 'type' => 'apr_hash_t *',
+ 'name' => 'h_value'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_module_symbol_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'modp'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_mpm_callback_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_out_filter_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_pcw_dir_cb_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_pcw_srv_cb_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_pod_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'pod_in'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'pod_out'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_reclaim_callback_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_regex_t',
+ 'elts' => [
+ {
+ 'type' => 'void *',
+ 'name' => 're_pcre'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 're_nsub'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 're_erroffset'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_regmatch_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'rm_so'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'rm_eo'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_rxplus_t',
+ 'elts' => [
+ {
+ 'type' => 'ap_regex_t',
+ 'name' => 'rx'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'subs'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'match'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'nmatch'
+ },
+ {
+ 'type' => 'ap_regmatch_t *',
+ 'name' => 'pmatch'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_sb_handle_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_scoreboard_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_slave_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_sload_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idle'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'busy'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'bytes_served'
+ },
+ {
+ 'type' => 'unsigned long',
+ 'name' => 'access_count'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_slotmem_callback_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_slotmem_instance_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_slotmem_provider_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)',
+ 'name' => 'doall'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t **inst, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)',
+ 'name' => 'create'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t **inst, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)',
+ 'name' => 'attach'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id, void**mem)',
+ 'name' => 'dptr'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len)',
+ 'name' => 'get'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len)',
+ 'name' => 'put'
+ },
+ {
+ 'type' => 'unsigned int(*)(ap_slotmem_instance_t *s)',
+ 'name' => 'num_slots'
+ },
+ {
+ 'type' => 'unsigned int(*)(ap_slotmem_instance_t *s)',
+ 'name' => 'num_free_slots'
+ },
+ {
+ 'type' => 'apr_size_t(*)(ap_slotmem_instance_t *s)',
+ 'name' => 'slot_size'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int *item_id)',
+ 'name' => 'grab'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id)',
+ 'name' => 'release'
+ },
+ {
+ 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id)',
+ 'name' => 'fgrab'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_slotmem_type_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_socache_instance_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_socache_iterator_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_unix_identity_t',
+ 'elts' => [
+ {
+ 'type' => 'uid_t',
+ 'name' => 'uid'
+ },
+ {
+ 'type' => 'gid_t',
+ 'name' => 'gid'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'userdir'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_version_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'major'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'minor'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'patch'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'add_string'
+ }
+ ]
+ },
+ {
+ 'type' => 'ap_vhost_iterate_conn_cb',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_watchdog_callback_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'ap_watchdog_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_access_compat_ap_satisfies_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_authn_cache_store_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_dbd_acquire_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_dbd_cacquire_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_dbd_close_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_dbd_open_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_dbd_prepare_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_find_loaded_module_symbol_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_ident_lookup_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_logio_add_bytes_in_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_logio_add_bytes_out_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_logio_get_last_bytes_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_register_rewrite_mapfunc_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_request_insert_filter_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_request_remove_filter_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_session_get_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_session_load_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_session_save_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_session_set_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_signal_server_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_watchdog_get_instance_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_watchdog_register_callback_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_ap_watchdog_set_callback_interval_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_authn_ap_auth_name_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_authn_ap_auth_type_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_authn_ap_list_provider_names_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_authz_ap_list_provider_names_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_authz_some_auth_required_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_modperl_interp_unselect_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_modperl_thx_interp_get_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_cache_check_subgroups_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_cache_checkuserid_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_cache_compare_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_cache_comparedn_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_cache_getuserdn_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_connection_close_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_connection_find_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_connection_open_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_connection_unbind_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_uldap_ssl_supported_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_xml2enc_charset_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_OFN_xml2enc_filter_t
+ ',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_abortfunc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_allocator_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_anylock_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'union apr_anylock_u_t',
+ 'name' => 'lock'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_array_header_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'elt_size'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nalloc'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'elts'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_brigade_flush',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_bucket',
+ 'elts' => [
+ {
+ 'type' => '_ANON 68',
+ 'name' => 'link'
+ },
+ {
+ 'type' => 'const apr_bucket_type_t *',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'void(*)(void *e)',
+ 'name' => 'free'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_bucket_brigade',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_bucket_list',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'bucket_alloc'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_file',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'fd'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'readpool'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'can_mmap'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_heap',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'alloc_len'
+ },
+ {
+ 'type' => 'void(*)(void *data)',
+ 'name' => 'free_func'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_mmap',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'name' => 'refcount'
+ },
+ {
+ 'type' => 'apr_mmap_t *',
+ 'name' => 'mmap'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_pool',
+ 'elts' => [
+ {
+ 'type' => 'apr_bucket_heap',
+ 'name' => 'heap'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_refcount',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'refcount'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_bucket_structs',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_bucket_type_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_func'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'is_metadata'
+ },
+ {
+ 'type' => 'void(*)(void *data)',
+ 'name' => 'destroy'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *b, const char **str, apr_size_t *len,
+ apr_read_type_e block)',
+ 'name' => 'read'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *e, apr_pool_t *pool)',
+ 'name' => 'setaside'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *e, apr_size_t point)',
+ 'name' => 'split'
+ },
+ {
+ 'type' => 'apr_status_t(*)(apr_bucket *e, apr_bucket **c)',
+ 'name' => 'copy'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_byte_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_child_errfn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_cmdtype_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_block_key_mode_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_block_key_type_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_block_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_config_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_driver_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_hash_add_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_hash_finish_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_hash_init_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_hash_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_crypto_hash_init_t *',
+ 'name' => 'init'
+ },
+ {
+ 'type' => 'apr_crypto_hash_add_t *',
+ 'name' => 'add'
+ },
+ {
+ 'type' => 'apr_crypto_hash_finish_t *',
+ 'name' => 'finish'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_crypto_key_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_crypto_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_datatype_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_datum_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dptr'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'dsize'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_dbd_driver_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbd_prepared_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbd_results_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbd_row_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbd_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbd_transaction_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbd_type_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dbm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_descriptor',
+ 'elts' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_dev_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dir_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dso_handle_sym_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_dso_handle_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_exit_why_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_file_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_fileattrs_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_filetype_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_finfo_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'valid'
+ },
+ {
+ 'type' => 'apr_fileperms_t',
+ 'name' => 'protection'
+ },
+ {
+ 'type' => 'apr_filetype_e',
+ 'name' => 'filetype'
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'name' => 'user'
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'name' => 'group'
+ },
+ {
+ 'type' => 'apr_ino_t',
+ 'name' => 'inode'
+ },
+ {
+ 'type' => 'apr_dev_t',
+ 'name' => 'device'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'nlink'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'csize'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'atime'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'ctime'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'filehand'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_getopt_err_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_getopt_option_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'optch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'has_arg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'description'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_getopt_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cont'
+ },
+ {
+ 'type' => 'apr_getopt_err_fn_t *',
+ 'name' => 'errfn'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'errarg'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ind'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'reset'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'char const *',
+ 'name' => 'place'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'interleave'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'skip_start'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'skip_end'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_gid_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_global_mutex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hash_do_callback_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hash_index_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hash_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hashfunc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_hdtr_t',
+ 'elts' => [
+ {
+ 'type' => 'iovec *',
+ 'name' => 'headers'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'numheaders'
+ },
+ {
+ 'type' => 'iovec *',
+ 'name' => 'trailers'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'numtrailers'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_in_addr_t',
+ 'elts' => [
+ {
+ 'type' => 'in_addr_t',
+ 'name' => 's_addr'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_ino_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_int64_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_interface_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_ipsubnet_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_kill_conditions_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_ldap_err_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'reason'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'msg'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'rc'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_ldap_opt_tls_cert_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'password'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_ldap_url_desc_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_ldap_url_desc_t *',
+ 'name' => 'lud_next'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'lud_scheme'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'lud_host'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'lud_port'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'lud_dn'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'lud_attrs'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'lud_scope'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'lud_filter'
+ },
+ {
+ 'type' => 'char **',
+ 'name' => 'lud_exts'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'lud_crit_exts'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_lockmech_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_md4_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t[4]',
+ 'name' => 'state'
+ },
+ {
+ 'type' => 'apr_uint32_t[2]',
+ 'name' => 'count'
+ },
+ {
+ 'type' => 'unsigned char[64]',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_md5_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t[4]',
+ 'name' => 'state'
+ },
+ {
+ 'type' => 'apr_uint32_t[2]',
+ 'name' => 'count'
+ },
+ {
+ 'type' => 'unsigned char[64]',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_xlate_t *',
+ 'name' => 'xlate'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_memcache_conn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_memcache_hash_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_memcache_server_func',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_memcache_server_status_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_memcache_server_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'host'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_memcache_server_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'apr_reslist_t *',
+ 'name' => 'conns'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'lock'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'btime'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_memcache_stats_t',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'version'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'uptime'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'time'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'pointer_size'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'rusage_user'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'rusage_system'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'curr_items'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'total_items'
+ },
+ {
+ 'type' => 'apr_uint64_t',
+ 'name' => 'bytes'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'curr_connections'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'total_connections'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'connection_structures'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'cmd_get'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'cmd_set'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'get_hits'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'get_misses'
+ },
+ {
+ 'type' => 'apr_uint64_t',
+ 'name' => 'evictions'
+ },
+ {
+ 'type' => 'apr_uint64_t',
+ 'name' => 'bytes_read'
+ },
+ {
+ 'type' => 'apr_uint64_t',
+ 'name' => 'bytes_written'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'limit_maxbytes'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'threads'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_memcache_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'nalloc'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'ntotal'
+ },
+ {
+ 'type' => 'apr_memcache_server_t **',
+ 'name' => 'live_servers'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'hash_baton'
+ },
+ {
+ 'type' => 'apr_memcache_hash_func',
+ 'name' => 'hash_func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'server_baton'
+ },
+ {
+ 'type' => 'apr_memcache_server_func',
+ 'name' => 'server_func'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_memcache_value_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_memnode_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_memnode_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_memnode_t **',
+ 'name' => 'ref'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'index'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'free_index'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'first_avail'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'endp'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_mmap_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'cntxt'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mm'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'size'
+ },
+ {
+ 'type' => '_ANON 66',
+ 'name' => 'link'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_opt_fn_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_dir_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_dso_handle_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_exp_time_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'tm_sec'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_min'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_hour'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_mday'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_mon'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_year'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_wday'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_yday'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tm_isdst'
+ },
+ {
+ 'type' => 'long int',
+ 'name' => 'tm_gmtoff'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'tm_zone'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_file_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_global_mutex_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_proc_mutex_t *',
+ 'name' => 'proc_mutex'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'thread_mutex'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_imp_time_t',
+ 'elts' => [
+ {
+ 'type' => '__time_t',
+ 'name' => 'tv_sec'
+ },
+ {
+ 'type' => '__suseconds_t',
+ 'name' => 'tv_usec'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_proc_mutex_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'crossproc'
+ },
+ {
+ 'type' => 'pthread_mutex_t *',
+ 'name' => 'pthread_interproc'
+ },
+ {
+ 'type' => 'pthread_mutex_t *',
+ 'name' => 'intraproc'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_proc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_shm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_sock_info_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_os_sock_t *',
+ 'name' => 'os_sock'
+ },
+ {
+ 'type' => 'sockaddr *',
+ 'name' => 'local'
+ },
+ {
+ 'type' => 'sockaddr *',
+ 'name' => 'remote'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'protocol'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_os_sock_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_thread_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_os_threadkey_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_other_child_rec_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pollcb_cb_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pollcb_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pollfd_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_datatype_e',
+ 'name' => 'desc_type'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'reqevents'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'rtnevents'
+ },
+ {
+ 'type' => 'apr_descriptor',
+ 'name' => 'desc'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'client_data'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_pollset_method_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pollset_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_pool_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_proc_mutex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_proc_t',
+ 'elts' => [
+ {
+ 'type' => 'pid_t',
+ 'name' => 'pid'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'in'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'out'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'err'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_procattr_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_queue_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_random_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_reslist_constructor',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_reslist_destructor',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_reslist_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_rmm_off_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_rmm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sdbm_datum_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'dptr'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'dsize'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_sdbm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_seek_where_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sha1_ctx_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uint32_t[5]',
+ 'name' => 'digest'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'count_lo'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'count_hi'
+ },
+ {
+ 'type' => 'apr_uint32_t[16]',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'local'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_shm_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_short_interval_time_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_shutdown_how_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sigfunc_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_signum_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_sockaddr_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'servname'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'family'
+ },
+ {
+ 'type' => 'apr_socklen_t',
+ 'name' => 'salen'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ipaddr_len'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'addr_str_len'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ipaddr_ptr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'union _ANON 1',
+ 'name' => 'sa'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_socket_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_socklen_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_ssize_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_strmatch_pattern',
+ 'elts' => [
+ {
+ 'type' => 'const char *(*)(const apr_strmatch_pattern *this_pattern,
+ const char *s, apr_size_t slen)',
+ 'name' => 'compare'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pattern'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'length'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_table_entry_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'name' => 'key_checksum'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_table_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_text',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'text'
+ },
+ {
+ 'type' => 'apr_text *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_text_header',
+ 'elts' => [
+ {
+ 'type' => 'apr_text *',
+ 'name' => 'first'
+ },
+ {
+ 'type' => 'apr_text *',
+ 'name' => 'last'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_thread_cond_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_mutex_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_once_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_pool_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_rwlock_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_start_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_thread_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_threadattr_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_threadkey_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_time_exp_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_usec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_sec'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_min'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_hour'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_mday'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_mon'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_year'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_wday'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_yday'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_isdst'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'tm_gmtoff'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uid_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uint16_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uint32_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uint64_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uintptr_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_uri_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'scheme'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'hostinfo'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'user'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'password'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'port_str'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'query'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'fragment'
+ },
+ {
+ 'type' => 'hostent *',
+ 'name' => 'hostent'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'is_initialized'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'dns_looked_up'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'dns_resolved'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_uuid_t',
+ 'elts' => [
+ {
+ 'type' => 'unsigned char[16]',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_version_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'major'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'minor'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'patch'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'is_dev'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_vformatter_buff_t',
+ 'elts' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'curpos'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'endpos'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_wait_how_e',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_xlate_t',
+ 'elts' => []
+ },
+ {
+ 'type' => 'apr_xml_attr',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ns'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'value'
+ },
+ {
+ 'type' => 'apr_xml_attr *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_xml_doc',
+ 'elts' => [
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'root'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'namespaces'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_xml_elem',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'ns'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'lang'
+ },
+ {
+ 'type' => 'apr_text_header',
+ 'name' => 'first_cdata'
+ },
+ {
+ 'type' => 'apr_text_header',
+ 'name' => 'following_cdata'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'parent'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'first_child'
+ },
+ {
+ 'type' => 'apr_xml_attr *',
+ 'name' => 'attr'
+ },
+ {
+ 'type' => 'apr_xml_elem *',
+ 'name' => 'last_child'
+ },
+ {
+ 'type' => 'apr_xml_ns_scope *',
+ 'name' => 'ns_scope'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'priv'
+ }
+ ]
+ },
+ {
+ 'type' => 'apr_xml_parser',
+ 'elts' => []
+ },
+ {
+ 'type' => 'cmd_parms',
+ 'elts' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'info'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_opts'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'override_list'
+ },
+ {
+ 'type' => 'apr_int64_t',
+ 'name' => 'limited'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'limited_xmethods'
+ },
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'xlimited'
+ },
+ {
+ 'type' => 'ap_configfile_t *',
+ 'name' => 'config_file'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'directive'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'temp_pool'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'const command_rec *',
+ 'name' => 'cmd'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'context'
+ },
+ {
+ 'type' => 'const ap_directive_t *',
+ 'name' => 'err_directive'
+ }
+ ]
+ },
+ {
+ 'type' => 'command_rec',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'cmd_func',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'cmd_data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'req_override'
+ },
+ {
+ 'type' => 'enum cmd_how',
+ 'name' => 'args_how'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'errmsg'
+ }
+ ]
+ },
+ {
+ 'type' => 'conn_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'vhost_lookup_data'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'local_addr'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'client_addr'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'client_ip'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'remote_host'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'remote_logname'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'local_ip'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'local_host'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'id'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'conn_config'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'notes'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'input_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'output_filters'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'sbh'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'bucket_alloc'
+ },
+ {
+ 'type' => 'conn_state_t *',
+ 'name' => 'cs'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'data_in_input_filters'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'data_in_output_filters'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'clogging_input_filters'
+ },
+ {
+ 'type' => 'signed int',
+ 'name' => 'double_reverse'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'aborted'
+ },
+ {
+ 'type' => 'ap_conn_keepalive_e',
+ 'name' => 'keepalive'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'keepalives'
+ },
+ {
+ 'type' => 'const struct ap_logconf *',
+ 'name' => 'log'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'log_id'
+ },
+ {
+ 'type' => 'apr_thread_t *',
+ 'name' => 'current_thread'
+ }
+ ]
+ },
+ {
+ 'type' => 'core_net_rec',
+ 'elts' => []
+ },
+ {
+ 'type' => 'htaccess_result',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'dir'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_opts'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'override_list'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'htaccess'
+ },
+ {
+ 'type' => 'const struct htaccess_result *',
+ 'name' => 'next'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_uri_t',
+ 'elts' => [
+ {
+ 'type' => 'apr_uri_t',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path_info'
+ }
+ ]
+ },
+ {
+ 'type' => 'module',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'version'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'minor_version'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'module_index'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dynamic_load_handle'
+ },
+ {
+ 'type' => 'module_struct *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'unsigned long',
+ 'name' => 'magic'
+ },
+ {
+ 'type' => 'void(*) (process_rec *process)',
+ 'name' => 'rewrite_args'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, char *dir)',
+ 'name' => 'create_dir_config'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, void *base_conf, void *new_conf)',
+ 'name' => 'merge_dir_config'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, server_rec *s)',
+ 'name' => 'create_server_config'
+ },
+ {
+ 'type' => 'void *(*) (apr_pool_t *p, void *base_conf,
+ void *new_conf)',
+ 'name' => 'merge_server_config'
+ },
+ {
+ 'type' => 'const command_rec *',
+ 'name' => 'cmds'
+ },
+ {
+ 'type' => 'void(*) (apr_pool_t *p)',
+ 'name' => 'register_hooks'
+ }
+ ]
+ },
+ {
+ 'type' => 'piped_log',
+ 'elts' => []
+ },
+ {
+ 'type' => 'process_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'short_name'
+ },
+ {
+ 'type' => 'const char * const *',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'argc'
+ }
+ ]
+ },
+ {
+ 'type' => 'request_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'connection'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'prev'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'main'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'the_request'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'assbackwards'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'proxyreq'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'header_only'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'proto_num'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'protocol'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hostname'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'request_time'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'status_line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'method_number'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'method'
+ },
+ {
+ 'type' => 'apr_int64_t',
+ 'name' => 'allowed'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'allowed_xmethods'
+ },
+ {
+ 'type' => 'ap_method_list_t *',
+ 'name' => 'allowed_methods'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'sent_bodyct'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'bytes_sent'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'range'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'clength'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'chunked'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_body'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_chunked'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'expecting_100'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'kept_body'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'body_table'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'remaining'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'read_length'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'headers_in'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'headers_out'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'err_headers_out'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'subprocess_env'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'notes'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'content_type'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'content_encoding'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'content_languages'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'vlist_validator'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'user'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'ap_auth_type'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'unparsed_uri'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'canonical_filename'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path_info'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'args'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'used_path_info'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'eos_sent'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'per_dir_config'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'request_config'
+ },
+ {
+ 'type' => 'const struct ap_logconf *',
+ 'name' => 'log'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'log_id'
+ },
+ {
+ 'type' => 'const struct htaccess_result *',
+ 'name' => 'htaccess'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'output_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'input_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'proto_output_filters'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'proto_input_filters'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'no_cache'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'no_local_copy'
+ },
+ {
+ 'type' => 'apr_thread_mutex_t *',
+ 'name' => 'invoke_mtx'
+ },
+ {
+ 'type' => 'apr_uri_t',
+ 'name' => 'parsed_uri'
+ },
+ {
+ 'type' => 'apr_finfo_t',
+ 'name' => 'finfo'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'useragent_addr'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'useragent_ip'
+ }
+ ]
+ },
+ {
+ 'type' => 'server_addr_rec',
+ 'elts' => [
+ {
+ 'type' => 'server_addr_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'virthost'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'host_addr'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'host_port'
+ }
+ ]
+ },
+ {
+ 'type' => 'server_rec',
+ 'elts' => [
+ {
+ 'type' => 'process_rec *',
+ 'name' => 'process'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'next'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'error_fname'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'error_log'
+ },
+ {
+ 'type' => 'ap_logconf',
+ 'name' => 'log'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'module_config'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'lookup_defaults'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'defn_name'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'defn_line_number'
+ },
+ {
+ 'type' => 'char',
+ 'name' => 'is_virtual'
+ },
+ {
+ 'type' => 'apr_port_t',
+ 'name' => 'port'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'server_scheme'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'server_admin'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'server_hostname'
+ },
+ {
+ 'type' => 'server_addr_rec *',
+ 'name' => 'addrs'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'keep_alive_timeout'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'keep_alive_max'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'keep_alive'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'names'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'wild_names'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'pathlen'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'limit_req_line'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'limit_req_fieldsize'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'limit_req_fields'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'context'
+ }
+ ]
+ },
+ {
+ 'type' => 'session_rec',
+ 'elts' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_uuid_t *',
+ 'name' => 'uuid'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'remote_user'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'entries'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'encoded'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'expiry'
+ },
+ {
+ 'type' => 'long',
+ 'name' => 'maxage'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'dirty'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cached'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'written'
+ }
+ ]
+ },
+ {
+ 'type' => 'subrequest_rec',
+ 'elts' => []
+ },
+ {
+ 'type' => 'unixd_config_rec',
+ 'elts' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'user_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'group_name'
+ },
+ {
+ 'type' => 'uid_t',
+ 'name' => 'user_id'
+ },
+ {
+ 'type' => 'gid_t',
+ 'name' => 'group_id'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'suexec_enabled'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'chroot_dir'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'suexec_disabled_reason'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_interp_t',
+ 'elts' => [
+ {
+ 'type' => 'modperl_interp_pool_t *',
+ 'name' => 'mip'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_requests'
+ },
+ {
+ 'type' => 'U8',
+ 'name' => 'flags'
+ },
+ {
+ 'type' => 'modperl_config_con_t *',
+ 'name' => 'ccfg'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'refcnt'
+ },
+ {
+ 'type' => 'unsigned long',
+ 'name' => 'tid'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_interp_pool_t',
+ 'elts' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'server'
+ },
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'modperl_tipool_config_t *',
+ 'name' => 'tipool_cfg'
+ },
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'parent'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_tipool_t',
+ 'elts' => [
+ {
+ 'type' => 'perl_mutex',
+ 'name' => 'tiplock'
+ },
+ {
+ 'type' => 'perl_cond',
+ 'name' => 'available'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'idle'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'busy'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'in_use'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'size'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'modperl_tipool_config_t *',
+ 'name' => 'cfg'
+ },
+ {
+ 'type' => 'modperl_tipool_vtbl_t *',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'type' => 'modperl_tipool_config_t',
+ 'elts' => [
+ {
+ 'type' => 'int',
+ 'name' => 'start'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'min_spare'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'max_spare'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'max'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'max_requests'
+ }
+ ]
+ }
+];
+
+
+1;
diff --git a/2_0_13/xs/tables/current24/ModPerl/FunctionTable.pm b/2_0_13/xs/tables/current24/ModPerl/FunctionTable.pm
new file mode 100644
index 0000000..9449ee3
--- /dev/null
+++ b/2_0_13/xs/tables/current24/ModPerl/FunctionTable.pm
@@ -0,0 +1,8580 @@
+package ModPerl::FunctionTable;
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# ! WARNING: generated by ModPerl::ParseSource/0.01
+# ! Mon Jul 1 12:38:19 2013
+# ! do NOT edit, any changes will be lost !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+$ModPerl::FunctionTable = [
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_access_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_apr_array_header2avrv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_array_header_t *',
+ 'name' => 'array'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_authen_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_authz_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_array_header_t *',
+ 'name' => 'modperl_avrv2apr_array_header',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'avrv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_brigade_dump',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'modperl_bucket_sv_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'args'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_files',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_per_dir',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_per_srv',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_callback_process',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_callback_run_handlers',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'modperl_hook_run_mode_e',
+ 'name' => 'run_mode'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_cgi_header_parse',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'body'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_child_init_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_cleanup_data_t *',
+ 'name' => 'modperl_cleanup_data_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_END',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_access_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_add_var',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_authen_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_authn_provider',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_authz_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_authz_provider',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_child_exit_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_child_init_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_cleanup_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_config_requires',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_fixup_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_header_parser_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_init_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_input_filter_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_max',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_max_requests',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_max_spare',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_min_spare',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_interp_start',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_load_module',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_log_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_map_to_storage_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_modules',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_open_logs_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_options',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_output_filter_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pass_env',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_perl',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_perldo',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pod',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pod_cut',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_post_config_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_post_config_requires',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_post_read_request_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_pre_connection_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_process_connection_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_cmd_push_filter_handlers',
+ 'args' => [
+ {
+ 'type' => 'MpAV **',
+ 'name' => 'handlers'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_cmd_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'MpAV **',
+ 'name' => 'handlers'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_requires',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_response_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_env',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_input_filter',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_output_filter',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_set_var',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_switches',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_trace',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'mconfig'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_trans_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_cmd_type_handlers',
+ 'args' => [
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'dummy'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U16 *',
+ 'name' => 'modperl_code_attrs',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'CV *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_apply_PerlModule',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_apply_PerlPostConfigRequire',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_apply_PerlRequire',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_con_t *',
+ 'name' => 'modperl_config_con_new',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_dir_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'dir'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_dir_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'basev'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'addv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_dir_t *',
+ 'name' => 'modperl_config_dir_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptmp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_options'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'conf'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert_parms',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert_request',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_config_insert_server',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_config_is_perl_option_enabled',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_config_req_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_req_t *',
+ 'name' => 'modperl_config_req_new',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_config_request_cleanup',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char **',
+ 'name' => 'modperl_config_srv_argv_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'argc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_srv_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_config_srv_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'basev'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'addv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_config_srv_t *',
+ 'name' => 'modperl_config_srv_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_const_compile',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'arg'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char **',
+ 'name' => 'modperl_constants_group_lookup_apache2_const',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char **',
+ 'name' => 'modperl_constants_group_lookup_apr_const',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char **',
+ 'name' => 'modperl_constants_group_lookup_modperl',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_constants_lookup_apache2_const',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_constants_lookup_apr_const',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_constants_lookup_modperl',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_croak',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ },
+ {
+ 'type' => 'const char*',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned long',
+ 'name' => 'modperl_debug_level',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_dir_config',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_configure_request_dir',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_configure_request_srv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_configure_server',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_default_populate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_hash_keys',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_hv_store',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_init',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_populate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_tie',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_unpopulate',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_request_untie',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_sync_dir_env_hash2table',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_config_dir_t *',
+ 'name' => 'dcfg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_sync_srv_env_hash2table',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_env_unload',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_error_strerror',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_status_t',
+ 'name' => 'rc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_errsv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_errsv_prepend',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pat'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_file2package',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'file'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U16 *',
+ 'name' => 'modperl_filter_attributes',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cvrv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_filter_t *',
+ 'name' => 'modperl_filter_mg_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_filter_t *',
+ 'name' => 'modperl_filter_new',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'modperl_filter_mode_e',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'input_mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_filter_resolve_init_handler',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_filter_runtime_add',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'modperl_filter_mode_e',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'modperl_filter_add_t',
+ 'name' => 'addfunc'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_fixup_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U32',
+ 'name' => 'modperl_flags_lookup_dir',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'U32',
+ 'name' => 'modperl_flags_lookup_srv',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_get_perl_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_anon_cnt_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_global_anon_cnt_next',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_global_get',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'modperl_global_get_pconf',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'server_rec *',
+ 'name' => 'modperl_global_get_server_rec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_init_pconf',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_init_server_rec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec * server_rec',
+ 'name' => 'arg1'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_lock',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_lock_pconf',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_lock_server_rec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'modperl_global_request',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'svr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_request_cfg_set',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_request_obj_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'svr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_request_set',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_set',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_set_pconf',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_set_server_rec',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'arg0'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_unlock',
+ 'args' => [
+ {
+ 'type' => 'modperl_global_t *',
+ 'name' => 'global'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_unlock_pconf',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_global_unlock_server_rec',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_handler_anon_add',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'anon'
+ },
+ {
+ 'type' => 'CV *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'CV *',
+ 'name' => 'modperl_handler_anon_get',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'anon'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_handler_anon_init',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_handler_anon_next',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'MpAV *',
+ 'name' => 'modperl_handler_array_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'MpAV *',
+ 'name' => 'base_a'
+ },
+ {
+ 'type' => 'MpAV *',
+ 'name' => 'add_a'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_files',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_per_dir',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_per_srv',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_pre_connection',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_desc_process',
+ 'args' => [
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_handler_t *',
+ 'name' => 'modperl_handler_dup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'h'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_equal',
+ 'args' => [
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'h1'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'h2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'MpAV **',
+ 'name' => 'modperl_handler_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'modperl_handler_action_e',
+ 'name' => 'action'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_lookup',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'MpAV **',
+ 'name' => 'modperl_handler_lookup_handlers',
+ 'args' => [
+ {
+ 'type' => 'modperl_config_dir_t *',
+ 'name' => 'dcfg'
+ },
+ {
+ 'type' => 'modperl_config_srv_t *',
+ 'name' => 'scfg'
+ },
+ {
+ 'type' => 'modperl_config_req_t *',
+ 'name' => 'rcfg'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'modperl_handler_action_e',
+ 'name' => 'action'
+ },
+ {
+ 'type' => 'const char **',
+ 'name' => 'desc'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_handler_make_args',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'AV **',
+ 'name' => 'avp'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_handler_name',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_handler_t *',
+ 'name' => 'modperl_handler_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_handler_t *',
+ 'name' => 'modperl_handler_new_from_sv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_perl_add_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'modperl_handler_action_e',
+ 'name' => 'action'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_handler_perl_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'MpAV **',
+ 'name' => 'handp'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'MpAV *',
+ 'name' => 'handlers'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_handler_resolve',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t **',
+ 'name' => 'handp'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_hash_seed_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_hash_seed_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_hash_tie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_hash_tied_object',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_hash_tied_object_rv',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_header_parser_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_hook_init',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_hook_pre_config',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_init',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_init_globals',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_init_vhost',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_input_filter_add_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_input_filter_add_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_input_filter_flush',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_input_filter_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'input_mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'modperl_input_filter_read',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'wanted'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_input_filter_write',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_clone_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_destroy',
+ 'args' => [
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_get',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_init',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_mip_walk',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'current_perl'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'parent_perl'
+ },
+ {
+ 'type' => 'modperl_interp_pool_t *',
+ 'name' => 'mip'
+ },
+ {
+ 'type' => 'modperl_interp_mip_walker_t',
+ 'name' => 'walker'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_mip_walk_servers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'current_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ },
+ {
+ 'type' => 'modperl_interp_mip_walker_t',
+ 'name' => 'walker'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_new',
+ 'args' => [
+ {
+ 'type' => 'modperl_interp_pool_t *',
+ 'name' => 'mip'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_pool_destroy',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_pool_get',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_pool_select',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_interp_pool_set',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'cleanup'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_interp_select',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_interp_unselect',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_apache_init',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_handle_tie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_io_handle_tied',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_handle_untie',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_perlio_override_stdin',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_perlio_override_stdout',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_perlio_restore_stdin',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_io_perlio_restore_stdout',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'GV *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_tie_stdin',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_io_tie_stdout',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_is_running',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_append',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'new_list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_first',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_last',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_new',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_prepend',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'new_list'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_remove',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'rlist'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_list_remove_data',
+ 'args' => [
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'modperl_list_t **',
+ 'name' => 'listp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_log_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_map_to_storage_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_mgv_append',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_mgv_as_string',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_mgv_compile',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_mgv_equal',
+ 'args' => [
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'mgv1'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'mgv2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_mgv_hash_handlers',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_mgv_last',
+ 'args' => [
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_mgv_last_name',
+ 'args' => [
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_mgv_lookup',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'GV *',
+ 'name' => 'modperl_mgv_lookup_autoload',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_mgv_t *',
+ 'name' => 'modperl_mgv_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_mgv_require_module',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_mgv_t *',
+ 'name' => 'symbol'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_mgv_resolve',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_handler_t *',
+ 'name' => 'handler'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logfailure'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_modglobal_hash_keys',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_modglobal_key_t *',
+ 'name' => 'modperl_modglobal_lookup',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_module_add',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'mod_cmds'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_module_config_get_obj',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'pmodule'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'v'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PTR_TBL_t *',
+ 'name' => 'modperl_module_config_table_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'create'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_module_config_table_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'table'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_newSVsv_obj',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'stashsv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_open_logs_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_options_t *',
+ 'name' => 'modperl_options_merge',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_options_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'modperl_options_t *new',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_options_t *',
+ 'name' => 'modperl_options_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'modperl_options_set',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_options_t *',
+ 'name' => 'o'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_output_filter_add_connection',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_output_filter_add_request',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_output_filter_flush',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_output_filter_handler',
+ 'args' => [
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'modperl_output_filter_read',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'wanted'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_output_filter_write',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_package_unload',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_av_push_elts_ref',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'dst'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'src'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_call_endav',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_call_list',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'AV *',
+ 'name' => 'subs'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_core_global_init',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_destruct',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_perl_destruct_level',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_do_join',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_do_sprintf',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sarg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_exit',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'status'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_gensym',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'pack'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_avcv_call',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_modglobal_key_t *',
+ 'name' => 'gkey'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'packlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_avcv_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_modglobal_key_t *',
+ 'name' => 'gkey'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'packlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_avcv_register',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_modglobal_key_t *',
+ 'name' => 'gkey'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'packlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_request_restore',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_global_request_save',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'HE *',
+ 'name' => 'modperl_perl_hv_fetch_he',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'HV *',
+ 'name' => 'hv'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'klen'
+ },
+ {
+ 'type' => 'U32',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_init_ids_server',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_perl_module_loaded',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_set',
+ 'args' => [
+ {
+ 'type' => 'modperl_perl_opcode_e',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_set_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_unset',
+ 'args' => [
+ {
+ 'type' => 'modperl_perl_opcode_e',
+ 'name' => 'idx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_perl_pp_unset_all',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_perl_sv_setref_uv',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'rv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'UV',
+ 'name' => 'uv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_pnotes',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'HV **',
+ 'name' => 'pnotes'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_pnotes_kill',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'cl_data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_post_config_handler',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pconf'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'plog'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'ptemp'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_post_post_config_phase',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_post_read_request_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_pre_connection_handler',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'csd'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_process_connection_handler',
+ 'args' => [
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_ptr2obj',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'ptr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_register_auth_provider',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback1'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback2'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_register_auth_provider_name',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_group'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_name'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'provider_version'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'callback1'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'callback2'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_register_handler_hooks',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_register_hooks',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'ssize_t',
+ 'name' => 'modperl_request_read',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_require_file',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logfailure'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_require_module',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'pv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logfailure'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_response_finish',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_response_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_response_handler_cgi',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_response_init',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_restart_count',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_restart_count_inc',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 'base_server'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_run',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_run_filter',
+ 'args' => [
+ {
+ 'type' => 'modperl_filter_t *',
+ 'name' => 'filter'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'modperl_server_desc',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'modperl_server_pool',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'modperl_server_user_pool',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_set_perl_module_config',
+ 'args' => [
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'cfg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_slurp_filename',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'tainted'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_spawn_proc_prog',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'command'
+ },
+ {
+ 'type' => 'const char ***',
+ 'name' => 'argv'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'script_in'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'script_out'
+ },
+ {
+ 'type' => 'apr_file_t **',
+ 'name' => 'script_err'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PerlInterpreter *',
+ 'name' => 'modperl_startup',
+ 'args' => [
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_str_toupper',
+ 'args' => [
+ {
+ 'type' => 'char *',
+ 'name' => 'str'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'modperl_sv2request_rec',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'server_rec *',
+ 'name' => 'modperl_sv2server_rec',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PTR_TBL_t *',
+ 'name' => 'modperl_svptr_table_clone',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'proto_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'source'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_delete',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_destroy',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void *',
+ 'name' => 'modperl_svptr_table_fetch',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_free',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'PTR_TBL_t *',
+ 'name' => 'modperl_svptr_table_new',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_split',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_svptr_table_store',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'PTR_TBL_t *',
+ 'name' => 'tbl'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'oldv'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'newv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_sys_dlclose',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'handle'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_sys_is_dir',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'modperl_table_get_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'table'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_val'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'do_taint'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_threaded_mpm',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_threads_started',
+ 'args' => []
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'modperl_thx_interp_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'thx'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_thx_interp_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'thx'
+ },
+ {
+ 'type' => 'modperl_interp_t *',
+ 'name' => 'interp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_add',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_destroy',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_init',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_tipool_t *',
+ 'name' => 'modperl_tipool_new',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_tipool_config_t *',
+ 'name' => 'cfg'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_list_t *',
+ 'name' => 'modperl_tipool_pop',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_putback',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'listp'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_requests'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_putback_data',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'num_requests'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tipool_remove',
+ 'args' => [
+ {
+ 'type' => 'modperl_tipool_t *',
+ 'name' => 'tipool'
+ },
+ {
+ 'type' => 'modperl_list_t *',
+ 'name' => 'listp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_create',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_tls_t **',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_create_request_rec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_get',
+ 'args' => [
+ {
+ 'type' => 'modperl_tls_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void **',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_get_request_rec',
+ 'args' => [
+ {
+ 'type' => 'request_rec * *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tls_reset_cleanup',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'modperl_tls_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_tls_reset_cleanup_request_rec',
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_set',
+ 'args' => [
+ {
+ 'type' => 'modperl_tls_t *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_tls_set_request_rec',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace',
+ 'args' => [
+ {
+ 'type' => 'const char *',
+ 'name' => 'func'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fmt'
+ },
+ {
+ 'type' => '...',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_level_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'level'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_trace_logfile_set',
+ 'args' => [
+ {
+ 'type' => 'apr_file_t *',
+ 'name' => 'logfile_new'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_trans_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'modperl_type_handler',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_uri_t *',
+ 'name' => 'modperl_uri_new',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_wbucket_flush',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_wbucket_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'add_flush_bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_wbucket_pass',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'modperl_wbucket_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'add_flush_bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'modperl_wbucket_write',
+ 'attr' => [
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'modperl_wbucket_t *',
+ 'name' => 'b'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'buf'
+ },
+ {
+ 'type' => 'apr_size_t *',
+ 'name' => 'wlen'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_xs_dl_handles_clear',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'modperl_xs_dl_handles_close',
+ 'args' => [
+ {
+ 'type' => 'void **',
+ 'name' => 'handles'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void **',
+ 'name' => 'modperl_xs_dl_handles_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'modperl_xs_sv2request_rec',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'CV *',
+ 'name' => 'cv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_cleanup',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_concat',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_destroy',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_first',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_APR__Brigade_flatten',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_insert_head',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Brigade_insert_tail',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Brigade_is_empty',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_last',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Brigade_length',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_all'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_next',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_pool_t *',
+ 'name' => 'mpxs_APR__Brigade_pool',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Brigade_prev',
+ 'args' => [
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__BucketAlloc_new',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Bucket_insert_after',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Bucket_insert_before',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'a'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'b'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Bucket_is_eos',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Bucket_is_flush',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_bucket *',
+ 'name' => 'mpxs_APR__Bucket_new',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'list'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_APR__Bucket_read',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Bucket_remove',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_bucket *',
+ 'name' => 'bucket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_APR__Bucket_setaside',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'b_sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Finfo_stat',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'fname'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'wanted'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'unsigned long',
+ 'name' => 'mpxs_APR__OS_current_thread_id',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Pool_clear',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Socket_fileno',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_int32_t',
+ 'name' => 'mpxs_APR__Socket_opt_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Socket_opt_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'opt'
+ },
+ {
+ 'type' => 'apr_int32_t',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_APR__Socket_poll',
+ 'args' => [
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 'timeout'
+ },
+ {
+ 'type' => 'apr_int16_t',
+ 'name' => 'reqevents'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_APR__Socket_recv',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_APR__Socket_timeout_set',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'apr_interval_time_t',
+ 'name' => 't'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__String_strfsize',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'size'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_APR__Table_EXISTS',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 't'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_APR__Table_FETCH',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_APR__Table_NEXTKEY',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'tsv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Table_copy',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Table_make',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'nelts'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Table_overlay',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'base'
+ },
+ {
+ 'type' => 'apr_table_t *',
+ 'name' => 'overlay'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_APR__URI_port',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uri'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'portsv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__URI_rpath',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'apr_uri'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__CmdParms_add_config',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__CmdParms_info',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__CmdParms_override_opts',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'cmd_parms *',
+ 'name' => 'parms'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Connection_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Connection_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_socket_t *',
+ 'name' => 'mpxs_Apache2__Connection_client_socket',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 's'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__Connection_get_remote_host',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'type'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'dir_config'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Connection_pnotes',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Connection_pnotes_kill',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Directive_as_hash',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'tree'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Directive_as_string',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_directive_t *',
+ 'name' => 'self'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Filter_ctx',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__Filter_fflush',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'filter'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'brigade'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__Filter_get_brigade',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'ap_input_mode_t',
+ 'name' => 'mode'
+ },
+ {
+ 'type' => 'apr_read_type_e',
+ 'name' => 'block'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'readbytes'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__Filter_pass_brigade',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'ap_filter_t *',
+ 'name' => 'f'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_Apache2__Filter_print',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_Apache2__Filter_read',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Filter_remove',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Filter_seen_eos',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Log_BOOT',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Log_log',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'logtype'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__MPM_BOOT',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__MPM_query',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'self'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'query_code'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__Module_add',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cmds'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__Module_ap_api_major_version',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__Module_ap_api_minor_version',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'module *',
+ 'name' => 'mod'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__Module_get_config',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'pmodule'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'ap_conf_vector_t *',
+ 'name' => 'v'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__Module_loaded',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_FILENO',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_GETC',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_OPEN',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'self'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg1'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg2'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_add_config',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'path'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'override_options'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_allow_override_opts',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_as_string',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_auth_name',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_auth_type',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_child_terminate',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_content_languages',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'languages'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_content_type',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'type'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_document_root',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'new_root'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_finfo_t *',
+ 'name' => 'mpxs_Apache2__RequestRec_finfo',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_finfo_t *',
+ 'name' => 'finfo'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_get_handlers',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'const char *',
+ 'name' => 'mpxs_Apache2__RequestRec_handler',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_is_perl_option_enabled',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_Apache2__RequestRec_location',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_location_merge',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'location'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_new',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'base_pool_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_no_cache',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'flag'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uri_t *',
+ 'name' => 'mpxs_Apache2__RequestRec_parsed_uri',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_pnotes',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_pnotes_kill',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_print',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_proxyreq',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_push_handlers',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_read',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_rflush',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_Apache2__RequestRec_sendfile',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'filename'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__RequestRec_set_basic_credentials',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'username'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'password'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__RequestRec_set_handlers',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_Apache2__RequestRec_set_last_modified',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'apr_time_t',
+ 'name' => 'mtime'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__RequestRec_subprocess_env',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_Apache2__RequestRec_write',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'apr_size_t',
+ 'name' => 'len'
+ },
+ {
+ 'type' => 'apr_off_t',
+ 'name' => 'offset'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'request_rec *',
+ 'name' => 'mpxs_Apache2__RequestUtil_request',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'svr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__ServerRec_add_config',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'lines'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_Apache2__ServerRec_get_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_is_perl_option_enabled',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_is_virtual',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_loglevel',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'loglevel'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_push_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_Apache2__ServerRec_set_handlers',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'server_rec *',
+ 'name' => 's'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__ServerUtil_BOOT',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ModPerl__Global_special_list_call',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ModPerl__Global_special_list_clear',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ModPerl__Global_special_list_register',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_ModPerl__Util_untaint',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_ap_allow_methods',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'long',
+ 'name' => 'mpxs_ap_get_client_block',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'buffer'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'bufsiz'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_ap_log_error',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'level'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'msg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_ap_register_auth_provider',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_ap_requires',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_ap_rprintf',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_ap_run_sub_req',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_ap_rvputs',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_ap_unescape_url',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'url'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_base64_decode',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_base64_encode',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_brigade_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'apr_bucket_alloc_t *',
+ 'name' => 'ba'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_ipsubnet_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'ipstr'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'mask_or_numbits'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_apr_password_validate',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'passwd'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'hash'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_pool_DESTROY',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_apr_pool_cleanup',
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'cleanup_data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_apr_pool_cleanup_register',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'p'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'cv'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'arg'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_pool_create',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'parent_pool_obj'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_apr_pool_parent_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_pool_t *',
+ 'name' => 'child_pool'
+ }
+ ]
+ },
+ {
+ 'return_type' => '',
+ 'name' => 'mpxs_apr_sockaddr_ip_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_sockaddr_t *',
+ 'name' => 'sockaddr'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_size_t',
+ 'name' => 'mpxs_apr_socket_send',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_socket_t *',
+ 'name' => 'socket'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_buf'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_len'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_interval_time_t',
+ 'name' => 'mpxs_apr_socket_timeout_get',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_apr_table_do',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'I32',
+ 'name' => 'items'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'mark'
+ },
+ {
+ 'type' => 'SV **',
+ 'name' => 'sp'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_apr_table_do_cb',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'key'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_thread_mutex_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'unsigned int',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_thread_rwlock_create',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_apr_uri_parse',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'classname'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'p_sv'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'uri_string'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'char *',
+ 'name' => 'mpxs_apr_uri_unparse',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_uri_t *',
+ 'name' => 'uptr'
+ },
+ {
+ 'type' => 'unsigned',
+ 'name' => 'flags'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uuid_t *',
+ 'name' => 'mpxs_apr_uuid_get',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_uuid_t *',
+ 'name' => 'mpxs_apr_uuid_parse',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'CLASS'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'buf'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_cleanup_run',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'void *',
+ 'name' => 'data'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_insert_auth_cfg',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'directive'
+ },
+ {
+ 'type' => 'char *',
+ 'name' => 'val'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_setup_client_block',
+ 'args' => [
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'int',
+ 'name' => 'mpxs_special_list_do',
+ 'attr' => [
+ 'static'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter*',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'package'
+ },
+ {
+ 'type' => 'mpxs_special_list_do_t',
+ 'name' => 'func'
+ }
+ ]
+ },
+ {
+ 'return_type' => 'modperl_interp_t *',
+ 'name' => 'mpxs_ModPerl__Interpreter_current',
+ 'attr' => [
+ 'static',
+ '__inline__'
+ ],
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'class'
+ }
+ ]
+ }
+];
+
+
+1;
diff --git a/2_0_13/xs/typemap b/2_0_13/xs/typemap
new file mode 100644
index 0000000..f9a9818
--- /dev/null
+++ b/2_0_13/xs/typemap
@@ -0,0 +1,89 @@
+TYPEMAP
+void * T_VPTR
+char_len * T_CHAR_LEN
+const char_len * T_CONST_CHAR_LEN
+
+######################################################################
+OUTPUT
+T_POOLOBJ
+ sv_setref_pv($arg, \"${ntype}\", (void*)$var);
+
+T_APACHEOBJ
+ sv_setref_pv($arg, \"${ntype}\", (void*)$var);
+
+T_HASHOBJ
+ $arg = modperl_hash_tie(aTHX_ \"${ntype}\", $arg, $var);
+
+T_VPTR
+ sv_setiv($arg, PTR2IV($var));
+
+T_UVPTR
+ sv_setuv($arg, PTR2UV($var));
+
+T_APR_TIME
+ sv_setnv($arg, (NV)(apr_time_sec($var)));
+
+T_UVOBJ
+ modperl_perl_sv_setref_uv(aTHX_ $arg, \"${ntype}\", (UV)$var);
+
+######################################################################
+INPUT
+T_PTROBJ
+ if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = INT2PTR($type, tmp);
+ }
+ else {
+ Perl_croak(aTHX_ SvROK($arg) ?
+ \"$var is not of type ${ntype}\" :
+ \"$var is not a blessed reference\");
+ }
+
+T_POOLOBJ
+ if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ if (tmp == 0) {
+ Perl_croak(aTHX_ \"invalid pool object (already destroyed?)\");
+ }
+ $var = INT2PTR($type, tmp);
+ }
+ else {
+ Perl_croak(aTHX_ SvROK($arg) ?
+ \"$var is not of type ${ntype}\" :
+ \"$var is not a blessed reference\");
+ }
+
+T_UVOBJ
+ if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) {
+ UV tmp = SvUV((SV*)SvRV($arg));
+ $var = INT2PTR($type, tmp);
+ }
+ else {
+ Perl_croak(aTHX_ SvROK($arg) ?
+ \"$var is not of type ${ntype}\" :
+ \"$var is not a blessed reference\");
+ }
+
+T_APACHEOBJ
+ $var = modperl_xs_sv2request_rec(aTHX_ $arg, \"$ntype\", cv)
+
+T_HASHOBJ
+ $var = modperl_hash_tied_object(aTHX_ \"${ntype}\", $arg)
+
+T_APACHEREF
+ $var = modperl_xs_sv2request_rec(aTHX_ $arg, \"$ntype\", cv)
+
+T_VPTR
+ $var = INT2PTR($type, SvIV(SvROK($arg) ? SvRV($arg) : $arg))
+
+T_UVPTR
+ $var = INT2PTR($type, SvUV(SvROK($arg) ? SvRV($arg) : $arg))
+
+T_APR_TIME
+ $var = (apr_time_t)(apr_time_from_sec(SvNV($arg)))
+
+T_CHAR_LEN
+ $var = (char *)SvPV($arg, ${var}_len)
+
+T_CONST_CHAR_LEN
+ $var = (const char *)SvPV($arg, ${var}_len)